代码如下:
const p = Promise.resolve();
(() => {
const implicit_promise = new Promise(resolve => {
const promise = new Promise(res => res(p));
promise.then(() => {
console.log('after:await');
resolve();
});
});
return implicit_promise;
})();
p.then(() => {
console.log('tick:a');
}).then(() => {
console.log('tick:b');
}).then(() => {
console.log('tick:c');
})
这段代码在node 11和浏览器中的输出顺序为:
tick:a
tick:b
after:await
tick:c
不应该先输出after:await么?
几点注意:
res=>res(p)
),会建立一个异步任务,并在异步任务里调用p.then(res)
。所以:
同步任务,
p
是一个已经 resolve 的 Promise 。匿名函数直接调用,SYNC1 执行,ASYNC2 执行。ASYNC2 执行并没有 resolvesync1_promise
(见以上第三点),而是增加了一个异步任务(异步1),在异步任务里将执行p.then(res)
。 于是,SYNC1 中的sync1_promise
并没有被 resolve ,ASYNC3 也并不会被放入异步队列。接下来,由于 p 已经 resolve,TICKA 被放入异步队列(异步2)。但是,其返回 Promise 由于 TICKA 并没有被调用(还在异步队列里),并没有被 resolve ,于是 TICKB 与 TICKC 均不会被放入异步队列。
异步1:执行
p.then(res)
,p 已经 resolve ,所以 res 被放入异步队列(异步3)异步2:执行 TICKA,输出 "tick:a"。同时,rosolve
p.then(TICKA)
返回的 Promise ,TICKB 被放入队列(异步4)异步3:执行
res()
,resolve 掉 SYNC1 中的sync1_promise
,于是在它的 then 里注册的 ASYNC3 被放入队列(异步5)异步4:执行 TICKB,输出 "tick:b"。同时,rosolve
p.then(TICKA).then(TICKB)
返回的 Promise ,TICKC 被放入队列(异步6)异步5:执行 ASYNC3,输出 "after:await" 。resolve
implicit_promise
。异步6:执行 TICKC,输出 "tick:c"