调用自身的异步函数

时间:2019-10-11 22:59:16

标签: javascript async-await

当您有需要按顺序完成的事情列表时,使异步函数本身调用是个好主意吗?

示例:

async continueWork(){

   if(!this.list.length)
     return;

   var next = this.list.shift();

   // do things with next

   await this.continueWork();
}

如果列表很大,会发生什么?会引起问题吗?

2 个答案:

答案 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);
  });

您可以通过在awaitcontinueWork内进行递归调用之前对其进行修复,以使调用堆栈不会堆积:

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)
    }
}