首先,JS是单线程的。所以代码的执行是有自己的执行顺序。
如: var a = "1",b = "2",c = "3";
console.log(c);
console.log(b);
console.log(a);
//打印在控制台的顺序是 3 2 1
假如是这样的例子呢?
var d = "4";
new Promise(function(reslove,reject){
console.log("我是promise1啊");
setTimeout(function(){
reslove();
},1000)
}).then(function(){
console.log("我是promise1的成功的回调啊");
})
setTimeout(function(){
console.log("我是计时器1啊");
})
setTimeout(function(){
console.log("我是计时器2啊");
},1000)
new Promise(function(reslove,reject){
console.log("我是promise2啊");
reject();
}) .then(function(){
console.log("我是promise2的成功回调啊");
}).catch(function(){
console.log("我是promise2的失败的回调啊");
})
console.log(d);
这时整个打印代码的执行顺序是什么样子的呢?
把代码放在浏览器的console里面去执行可以发现顺序是这样的。
/*
我是promise1啊
我是promise2啊
4
我是promise2的失败的回调啊
我是计时器1啊
我是promise1的成功的回调啊
我是计时器2啊
*/
如果你答对了执行顺序,除了猜对的,说明你对执行顺序是很了解的,那可以跳过本文章。如果是猜对的或者是错了。可以往下读。帮你理清执行顺序!
这里要引入几个概念
这里可以看出来任务的执行栈的执行方式是先主线程执行同步任务,主线程完成之后是异步任务。
而宏任务跟微任务是相对于广义的同步,异步执行的更精细化的定义
整个代码从宏任务进入主线程。
new Promise()是promise实例化会被直接执行所以先打印的是 我是promise1啊。
然后执行到内部的setTimeout会放置到异步里面的宏任务的Event Queue
then的方法会放置在微任务里面等待状态返回调用
继续走就遇到计时器1跟计时器2两个计时器同样被放置到宏任务的Event Queue
之后是第一个new Promise()直接执行打印 我是promise2啊
相应的then跟catch统统放到微任务里面去。所以继续执行console.log(d),这是打印 4
第一个宏任务的主线程执行完毕。接着执行微任务
但是第一个promise的then并没有状态返回被调用所以没有执行,而第二个promise有reject的调用而被执行,
所以,打印出 我是promise2的失败的回调啊
微任务暂时执行结束,继续执行宏任务的 Event Queue。计时器先执行计时器1 打印 我是计时器1啊
然后执行同样被延迟1S但是先放入的第一个new promise里面的settimeout 然后执行已经在微任务里面等待的成功的回调所以执行 我是promise1的成功的回调啊
最后执行计时器2完成 打印 我是计时器2啊