借鉴在《ECMAScript 6 入门》一书中描述的内容,Promise.resolve('foo')
等价于new Promise(resolve => resolve('foo'))
。如果resolve
的参数是一个promise
对象呢,是否仍然等价?
Demo1
let p1 = Promise.resolve(1);
let p2 = new Promise(resolve => resolve(1));
console.log(p1);
console.log(p2);
// Promise {<fulfilled>: 1}
// Promise {<fulfilled>: 1}
Demo2
let p = Promise.resolve(1);
let p3 = Promise.resolve(p);
let p4 = new Promise(resolve => resolve(p));
console.log(p3);
console.log(p4);
// Promise {<fulfilled>: 1}
// Promise {<pending>}
发现p3和p4的状态不一样了
Demo3
let p = Promise.resolve(1);
let p3 = Promise.resolve(p);
let p4 = new Promise(resolve => resolve(p));
p4.then(() => console.log('promise1'))
.then(() => console.log('promise2'));
p3.then(() => console.log('promise3'))
.then(() => console.log('promise4'))
.then(() => console.log('promise5'));
// promise3
// promise4
// promise1
// promise5
// promise2
发现p4
中指定的回调函数延迟了两个时序执行。再看Demo4相关的等价代码,推迟了两个时序的then执行。
Demo4
Promise.resolve(thenable)
等价于new Promise(resolve => { Promise.resolve().then(()=>{ p.then(resolve); }); });
let p = Promise.resolve(1);
let p3 = Promise.resolve(p);
//Promise.resolve(thenable) 等价于如下代码
let p4 = new Promise(resolve => {
Promise.resolve().then(()=>{
p.then(resolve);
});
});
p4.then(() => console.log('promise1'))
.then(() => console.log('promise2'));
p3.then(() => console.log('promise3'))
.then(() => console.log('promise4'))
.then(() => console.log('promise5'));
第一次宏任务执行,遇到如上图选中的A区块,会将A加入到微任务队列,继续执行,接着会将() => console.log('promise3')
加入到微任务队列,本次循环结束之前会执行微任务队列中的这两个回调函数。
A区块的执行会将resolve放入队列,() => console.log('promise3')
执行打印出promise3
;执行完毕会将() => console.log('promise4')
放入队列,继续执行。
resolve执行,会通知p4
状态改变为fulfilld
,进而将() => console.log('promise1')
放入队列,() => console.log('promise4')
执行,打印出promise4
,执行完毕会将() => console.log('promise5')
放入队列。因此一次打印promise1
和promise5
参考
Promise.resolve()与new Promise(r => r(v))
async await 和 promise微任务执行顺序问题
What’s the difference between resolve(thenable) and resolve(‘non-thenable-object’)?