我对新的 Promise((resolve, reject) => {[loop]}) 正在阻塞而 Promise.resolve().then([loop]) 不是感到困惑



我有三个使用console.time内置函数的基准测试(之前基准,基准测试和之后基准)。

这两个代码非常相同。但是,区别在于JS承诺API的构造。

第一个在承诺解析中包含一个循环,第二个在承诺中包含一个循环。

我不确定为什么第三个控制台.log("后循环")需要更长的时间才能完成,我将其设计为异步。感谢您抽出宝贵时间阅读本文。

承诺决心

环路
前 基准:0.836ms 环路
后基准:40.987ms 基准:41.202ms


然后承诺

环路
前 基准:1.122ms 环路
后基准:2.872ms 基准:43.705ms


我环顾了堆栈溢出,但我找不到与此相关的任何答案。

第一种承诺

console.time("beforeBenchmark");
console.time("benchmark");
console.time("afterBenchmark");
console.log("before loop");
console.timeEnd("beforeBenchmark");
let i = 0;
let promise = new Promise(( resolve, reject ) =>
{
while (i < 10000000)
{
i++;
}
resolve();
}).then(() =>
{    
console.timeEnd("benchmark")
});
console.log("after loop");
console.timeEnd("afterBenchmark");

结果

before loop
beforeBenchmark: 0.836ms
after loop
afterBenchmark: 40.987ms
benchmark: 41.202ms

第二种承诺

console.time("beforeBenchmark");
console.time("benchmark");
console.time("afterBenchmark");
console.log("before loop");
console.timeEnd("beforeBenchmark");
let i = 0;
let promise = Promise.resolve().then(() =>
{
while (i < 10000000)
{
i++;
}
console.timeEnd("benchmark")
});

console.log("after loop");
console.timeEnd("afterBenchmark");

结果

before loop
beforeBenchmark: 1.122ms
after loop
afterBenchmark: 2.872ms
benchmark: 43.705ms

Promise构造函数同步运行。如果new Promise(...中有阻塞代码,则该代码将在构造的 Promise 下方的下一行运行之前运行(并阻止)。这就是为什么您的第一个代码段有afterBenchmark: 40.987ms.

另一方面,.then回调只会在清除当前事件循环后运行(一旦所有同步代码都运行完毕) - 它就像setTimeout(fn, 0)(不完全相同,因为setTimeout将在事件循环的下一次迭代上运行,而不是在当前循环结束时运行, 但它非常相似)。因此,第二个代码中的afterBenchmark会在then运行之前、阻塞循环运行之前记录下来。

最新更新