当您有需要按顺序完成的事情列表时,使异步函数本身调用是个好主意吗?
例:
async continueWork(){
if(!this.list.length)
return;
var next = this.list.shift();
// do things with next
await this.continueWork();
}
如果列表很大,会发生什么?会引起问题吗?
最佳答案
是的,这可能会引起问题。每个continueWork
调用都放在最后一个continueWork
顶部的调用堆栈中,这可能导致溢出:
let i = 0;
async function continueWork() {
i++;
if (i < 1e5) {
await continueWork();
}
}
continueWork()
.then(() => console.log('ok'))
.catch((err) => {
console.log('err');
console.log(err.stack);
});
您可以通过
await
在continueWork
内部进行递归调用之前对其进行修复,以使调用堆栈不会堆积:let i = 0;
async function continueWork() {
i++;
await Promise.resolve();
if (i < 1e5) {
await continueWork();
}
}
continueWork()
.then(() => console.log('ok'))
.catch((err) => {
console.log('err');
console.log(err.stack);
});
重要的是要确保在调用堆栈清空之前没有大量同步函数调用。
await
(或.then
)确保await
或.then
回调之后的内容在微任务中执行(仅在清除调用堆栈后才会发生)。