当您有需要按顺序完成的事情列表时,使异步函数本身调用是个好主意吗?
示例:
async continueWork(){
if(!this.list.length)
return;
var next = this.list.shift();
// do things with next
await this.continueWork();
}
如果列表很大,会发生什么?会引起问题吗?
答案 0 :(得分:4)
是的,这可能会引起问题。每个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);
});
重要的是要确保在调用堆栈清空之前没有大量的 synchronous 函数调用。 await
(或.then
)确保await
或.then
回调之后的内容在微任务中执行(仅在清除调用堆栈后才会发生)。
答案 1 :(得分:0)
为什么不使用好时光?
async continueWork(){
while(this.list.length){
let next = this.list.shift()
await do_things_with_next(next)
}
}