跳到主要内容

promise

Promise.resolve()
.then(() => {
console.log(0);
return Promise.resolve(4);
})
.then((res) => {
console.log(res);
});
Promise.resolve()
.then(() => {
console.log(1);
})
.then(() => {
setTimeout(() => {
console.log('when will i run?');
}, 0);
console.log(2);
})
.then(() => {
console.log(3);
})
.then(() => {
console.log(5);
});
Promise.resolve()
.then(() => {
console.log(0);
return Promise.resolve(4).then((res) => {
console.log('x');
});
})
.then((res) => {
console.log(res);
});
Promise.resolve()
.then(() => {
console.log(1);
})
.then(() => {
setTimeout(() => {
console.log('when will i run?');
}, 0);
console.log(2);
})
.then(() => {
console.log(3);
})
.then(() => {
console.log(5);
});
console.log('end');
// end
// 0
// 1
// x
// 2
// 3
// undefined
// 5
// when will i run?

console.log(1);被推入微队列,处于 pending 状态,所以后续 then 方法没有执行,直到主线程空闲,微队列中的任务才会被执行。

https://promisesaplus.com/#point-49

当 then 方法返回一个 Promise 时,后续 then 方法会等待该 Promise 状态变更后再执行。这是 prmiseA+规范中的要求。

在浏览器实现中,当 then 方法返回一个 Promise 时,会将此 Promise 放入微队列中,等待主线程空闲时执行。

解释如下:

  • Promise.resolve() 创建了一个已经解决的 Promise 对象。
  • .then() 方法接受一个函数作为参数,该函数将在 Promise 解决时被调用。
  • 在第一个 .then() 中,我们打印了数字 0,然后返回了一个新的已解决的 Promise 对象,值为 4。
  • 在第二个 .then() 中,我们打印了上一个 Promise 的结果(也就是 4)。
  • 在第三个 .then() 中,我们打印了数字 1。
  • 在第四个 .then() 中,我们设置了 setTimeout,然后打印了数字 2。由于 setTimeout 是异步的,所以它不会立即执行,而是会在下一个事件循环迭代中执行。
  • 在第五个 .then() 中,我们打印了数字 3。
  • 在第六个 .then() 中,我们打印了数字 5。
  • 最后,setTimeout 被执行,打印了 "when will i run?"。

需要注意的是,虽然 setTimeout 是在第四个 .then() 中设置的,但由于它是宏任务(MacroTask),所以它会在所有的微任务(MicroTask)执行完毕后才执行。这就是为什么 "when will i run?" 会在数字 5 之后打印的原因。