promise经典题目
当一个promise进入settled状态时,它后面的then回调会被置入微任务队列。
settle的时机,决定了回调函数进入微队列的时间,决定了执行顺序。
代码一:
new Promise((resolve) => {
resolve();
Promise.resolve({
then: function(resolve, reject) {
console.log(1);
resolve();
},
}).then(() => console.log(2));
console.log(0);
}).then(() => console.log(3));
解析:从第三行开始
当Promise.resolve()接收一个thenable参数时,即刻产生了一个promise1,并返回这个promise1,这个promise1被 settle的时机是thenable.then的resolve被调用时。
当Promise.resolve({ then: ... })执行完成,将thenable.then放入微任务队列,并返回一个promise1,然后执行了console.log(0)
console.log(0)执行完成后,(resolve) => { .... },这个代码块执行结束,调用栈清空,同时返回了一个promise0。
promise0立刻转为settle状态,致使() => console.log(3) 进入微任务队列
thenable.then在微任务队列弹出,执行console.log(1); resolve();
promise1 settle,导致() => console.log(2)进入微任务队列;
此时,微任务队列内还剩() => console.log(3)和() => console.log(2),根据入队顺序,依次被调用。
代码二:
new Promise((resolve) => {
resolve();
Promise.resolve().then(() => console.log(2));
}).then(() => console.log(4));
解析:依次执行
new Promise(...
resolve();
Promise.resolve().then(() => console.log(2)),此时Promise.resolve产生了一个promise1,并立即settle,导致console.log(2)进入微任务队列
new Promise(... 构造函数返回,生成了一个promise2。promise2即刻settle,导致() => console.log(4)进入微任务队列。
调用栈清空,开始依次执行微任务。