当我们在微任务队列中从then()链返回值和Promise.resolve时,会发生什么



这里我有一个简单解决的承诺。

let promise = new Promise((resolve,reject)=>{
resolve("resolved");
});

当我在.then链中使用Promise作为返回值时,我开始感到困惑,如下所示:

promise.then(resolve=>{
console.log(resolve);
return Promise.resolve(2);
}).then(resolve=>{
console.log(resolve);
});
promise.then(resolve=>{
console.log(resolve)
return 3;
}).then(resolve=>{
console.log(resolve);
});

这些链的输出为:1 1 3 2我期望看到的:1 1 2 3

但如果我把return Promise.resolve(2);变成return 2,就像这里一样:

promise.then(resolve=>{
console.log(resolve);
return 2;
}).then(resolve=>{
console.log(resolve);
});
promise.then(resolve=>{
console.log(resolve)
return 3;
}).then(resolve=>{
console.log(resolve);
});

我会得到我最初认为会得到的输出(1 1 2 3(。

那么,这里有人能解释为什么输出会根据使用和不使用Promise.resolve()而变化吗?

顺便说一句,我问这个问题纯粹是出于学术原因!

Promises的thens在微任务期间解析。在.then中,如果返回一个普通值,如2或3,则下一个链接到它上的.then将在下一次清除调用堆栈时运行。但是,如果您返回Promise,则必须先打开它,然后再进行下一个.then

在您的第一个代码中,一旦调用堆栈被清除,第一个微任务就会运行。其中一个"打开"Promise.resolve(2),并在微任务队列中对.then回调进行排队。相反,3不需要展开,因此它的.then在此时立即运行,而不必等待,记录3。

微任务队列的首要任务是2.then,记录2。

尽管如此,在真实的代码中,你不应该依赖这种时间安排,因为这有点令人困惑——如果这是一个问题,最好重新构建代码,这样就不用担心了。

因为在情况1中返回了一个新的Promise,所以它将在下一个tick中得到解决。

每次搜索微任务Q时,Q中的承诺都会得到解决(不仅是承诺,而且这与这个问题有关(。在情况1中,Promise.resolve(2)得到解决的同时resolve=>{ console.log(resolve) return 3; }得到解决。

现在,下一个micro Q在Q上有Promise.resolve(2)的附带承诺。这增加了两种情况之间的延迟。

最新更新