在下面的代码中,有一个outer
函数和一个inner
函数。 outer
应该await
inner
,并在完成后返回。 inner
返回Promise
,超时后即可完成。我希望在outer
完成后立即返回Promise
函数:
const outer = async () => {
let counter = 0;
const inner = async () => {
console.log('inner');
return new Promise((fulfill, reject) => {
if (++counter === 3) {
console.log('fulfill');
fulfill();
return;
}
setTimeout(() => inner(), 1000);
});
};
return await inner();
};
outer().then(() => console.log('outer done'));
outer
永远不会完成。请注意,没有outer done
输出:
inner
inner
inner
fulfill
在以下代码中outer
完成。它返回Promise
本身,inner
函数实现它:
const outer = async () => {
return new Promise((fulfill, reject) => {
let counter = 0;
const inner = async () => {
console.log('inner');
if (++counter === 3) {
console.log('fulfill');
fulfill();
return;
}
setTimeout(() => inner(), 1000);
};
inner().catch(err => reject(err));
});
};
outer().then(() => console.log('outer done'));
输出:
inner
inner
inner
fulfill
outer done
我认为在这两种情况下行为都应该相似。任何人都可以看到并解释其中的差异吗?
答案 0 :(得分:4)
您从未在fullfill
中调用inner
函数。你创造了一堆新的Promises,你只告诉了它已经解决的最后一个承诺。
让我们来看看您的异步任务:
{
if (++counter === 3) {
console.log('fulfill');
fulfill();
return;
}
setTimeout(() => inner(), 1000);
}
在第一次调用inner
时,即此部分:
return await inner();
counter
为0.这意味着不会执行整个if
块。在其余代码中,它从未调用fulfill
函数,因此承诺永远不会得到解决。
如果您的生产代码库中存在此代码(或此样式的代码),我的建议是您应该重写它。
要快速修复 ,您可以这样做:
setTimeout(() => inner().then(() => fulfill()), 1000);