前两天看到一个promise题,要弄懂这道题需要以下知识(当然没有大概也可以看懂吧) 。
此题的解释是错的,对不起!!!
此题的解释是错的,对不起!!!
此题的解释是错的,对不起!!!
这篇文章关于任务队列的部分写的是错的,在开始的时候任务队列内就已经存在所有的任务,等待主线程取用。因为promise的.then、.catch 和 .finally 都是异步的
return Promise.resolve()的解释在v8内核是正确的
此题正解应该是结合promise、promise状态、异步、队列、事件循环来解释),等我以后有空了再完善。
ps:这个题的结果仅限于v8内核的浏览器(chrome,edge),其他浏览器或许不是一样的结果
- 对事件循环有些了解
- 基础promise知识(Promise.resolve().then()这句代码会创建一个微队列任务)
看题:
Promise.resolve().then(() => {
console.log(0);
return Promise.resolve(4)
}).then(res => {
console.log(res);
})
Promise.resolve().then(() => {
console.log(1);
}).then(() => {
console.log(2);
}).then(() => {
console.log(3);
}).then(() => {
console.log(5);
}).then(() => {
console.log(6);
})
输出结果为 0123456
这个题的争议点在return Promise.resolve(4) 在v8内核的浏览器中此处会创建一个微队列任务来执行它,就相当于又将return Promise.resolve(4)包了一层(这是最难的点)
下面是这个题的详解:
第一部分记为P1,第二部分记为P2 ,微队列记为queue,输出记为log, 全部输出记为 result
1. 主线程执行完代码后创建一个微队列,微队列是下面这样:
1.1.P1执行完向微队列添加一个任务:
queue: {console.log(0); return Promise.resolve(4)}
1.2.P2执行完向微队列添加一个任务
queue: {log(0); return Promise.resolve(4)},log(1)
result:null
2. 主线程从微队列取任务: {console.log(0); return Promise.resolve(4)}
任务输出0,然后创建一个微队列任务去执行 return Promise.resolve(4),
所以此时queue为:
queue:log(1), return Promise.resolve(4)
result:0
3.再次取任务log(1) :输出1 并且向微队列添加log2
queue: return Promise.resolve(4), log(2)
result:0,1
4.取出return Promise.resolve(4)并执行,执行结果为创建了一个微队列任务Promise.resolve().then(4)
queue:log(2),Promise.resolve().then(4)
result:0,1
5.取出log(2)并执行,创建了一个微队列任务log(3)
queue:Promise.resolve().then(4), log(3)
result:0,1,2
6.取出Promise.resolve().then(4)并执行,创建了一个微队列任务log(4).
即:log(res) ===log(4)
queue:log(3),log(4)
result:0,1,2
7.取出log(3)并执行,创建了一个微队列任务log(5)
queue:log(4),log(5)
result:0,1,2,3
8.取出log(4)并执行, 第一段代码P1至此执行结束。
queue:log(5)
result:0,1,2,3,4
9.取出log(5)添加log(6)
queue:log(6)
result:0,1,2,3,4,5
10.取出log(6)第二部分P2执行结束,程序执行结束。
qqueue:null
result:0,1,2,3,4,5,6