这里我有一个简单解决的承诺。
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的then
s在微任务期间解析。在.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)
的附带承诺。这增加了两种情况之间的延迟。