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)进入微任务队列。

调用栈清空,开始依次执行微任务。