提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
目录
1.promise概述
(1)promise是异步编程的一种解决方案。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
(2)Promise 异步操作有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。
(3)Promise 对象只有:从 pending 变为 fulfilled 和从 pending 变为 rejected 的状态改变。只要处于 fulfilled 和 rejected ,状态就不会再变了即 resolved(已定型)。
(4)Promise是一个构造函数,其原型上有then、catch方法,对象上有reject、resolve方法。
(1)同步、异步的设计思想
同步、异步的概念
同步:按照一定的顺序去执行,执行完一个才能执行下一个
异步:执行顺序是不确定的,由触发条件决定,什么时间执行也是不确定的,即使是定时器(下面做解释),异步处理可以同时执行多个。
通过代码理解:
同步:代码的书写顺序和代码的执行顺序一样
异步:代码的书写顺序和代码的执行顺序不一样
阻塞:在等待结果的过程中,不能干其他事,线程被挂起,直到结果返回。
非阻塞:在等待结果的过程中,还能干其他事,线程不会被阻塞。
同步和异步的区别:同步是按照执行顺序一步一步往下执行的,异步是按照代码执行顺序的时候,可以去执行其他的,不按照顺序来的,执行的顺序是不确定的。
同步的设计思想
function createData(){ return parseInt((Math.random()*(90-50)+50)) } var obj={ data:100, tool:function(){ var data=createData() this.data=data } } obj.tool() console.log(obj.data)
运行结果:
异步的设计思想-回调函数
function createData(callback) { callback(parseInt((Math.random() * (90 - 50) + 50))) } var obj = { data: 100, tool: function() { var a = 20; createData((n) => { this.data = n }) var b=100; for(;;){} } } obj.tool() console.log(obj.data)
function fn (cb,n) { for(var i=0;i<n;i++){} cb() } //异步函数 console.log(1) fn(function(){console.log(3)},10000) //这个函数内部也有一个打印 3 console.log(5) // fn函数不可能是异步函数 但是js的底层 c/c++是有不阻塞代码的异步函数的 setTimeout(function(){console.log(4)},1000) console.log(2)
function fn (cb,n) { for(var i=0;i<n;i++){} cb() } //异步函数 console.log(1) fn(function(){console.log(3)},10000) //fn阻塞,先执行完在执行输出5 console.log(5) // fn函数不可能是异步函数 但是js的底层 c/c++是有不阻塞代码的异步函数的 setTimeout(function(){console.log(4)},1000) console.log(2) //fn延迟了,所以先打印2在打印输出4
运行结果:
(2)阻塞异步
同步阻塞:张三在用烧水壶烧开水,直到开水烧开。
同步非阻塞:张三在用烧水壶烧开水的时候,就去做其他事情了。
异步阻塞:张三在用晌水壶烧开水,直到开水烧开。
异步非阻塞:张三在用晌水壶烧开水,就去做其他事情了。
阻塞异步的例子:
//阻塞异步
fn1(function(){console.log(1)})
//官方提供的非阻塞异步函数
setTimeOut(function(){console.log(2)})
//阻塞异步
fn3(function(){console.log(3)})
(3)promise语法
setTimeout()函数是一个非阻塞的异步函数
setTimeout(()=>{console.log(11)},3000)
setTimeout(()=>{console.log(22)},4000)
后端的fs.readFile()函数也是一个非阻塞的异步函数
es6 中的promise对象的then函数也是一个非阻塞的异步函数
1.Promise是一个ES5已经出现了 ES6直接写入标准
2.Promise是一个构造函数 创建了一个数据容器
数据容器:map set arr object,它们是被动产生数据 给它添加数据
Promise主动产生数据 不用给它添加数据 而是它自己产生数据
例如:
var p1=new Promise(function(n1,n2){ var n=Math.random() n1(n) //n1调用了 就代表p1产生了数据 })
运行结果:
(4)then()函数
then函数是一个异步非阻塞函数
then的规则:
then函数的返回值是 一个新的promise对象
是then传入的回调函数的返回值:
1.如果是一个promise对象 那么就是它
2.如果不是一个promise对象,那么就会把函数的结果包装为一个生成数据了的promise对象
var p1=new Promise(function(n1,n2){ var n=Math.random() n1(n) //n1调用了 就代表p1产生了数据 }) var re=p1.then(function(data){ console.log(data,111) return 200 }) console.log(222) re.then((data)=>{console.log(data,333)})
运行结果:
程序举例:
运行结果:
2.任务队列和事件循环
(1)异步编程中最难的 任务的队列分类 和事件循环
(2)任务指的就是js代码中的运行的代码
(3)fn() 代表了fn任务的运行 ,脚本也是一个任务,计时器的运行也是一个任务,promise也是一个任务
(4)任务分为同步的任务 和异步的任务
同步任务:同步任务是指在主线程上排队执行的任务,只有前一个任务执行完毕,才能继续执行下一个任务。
异步任务:异步任务是指不进入主线程,而进入任务队列的任务,只有任务队列通知主线程,某个异步任务可以执行了,该任务才会进入主线程。
事件循环
同步任务举例:
function fn(){}
var a=new Array()
var b=fn()
异步任务举例:
setTimeout(fn,1000)
p1.then(fn)
console.log(123)
程序举例:
console.log(4) setTimeout(() => { setTimeout(()=>{console.log(6)},0) console.log(1) var p2 = new Promise((n1, n2) => { n1(1000) }) p2.then(()=>{console.log(7)}) }, 0) setTimeout(() => { setTimeout(() => {console.log(2)}, 200) var p3 = new Promise((n1, n2) => { n1(1000) }) p3.then(()=>{console.log(8)}) console.log(2) }, 0) var p1 = new Promise((n1, n2) => { n1(1000) }) p1.then(() => {console.log(3)}) console.log(5)
运行结果:
异步任务的队列优先级: 异步宏任务先执行 然后在执行异步微任务
事件循环
任务开启后:内部执行的时候可能会有新的任务
1. 先执行同步任务
2.添加新的宏任务到队列中 添加新的的异步微任务
3.执行异步微任务
那些属于宏任务:
宏:脚本就是一个宏任务
脚本运行 执行第一个宏任务: