简体   繁体   English

调用自身的异步 function

[英]Async function that calls itself

Is it a good idea to make a async function call itself, when you have a list of things that need to be done in order?当您有一个需要按顺序完成的事情列表时,自己进行异步 function 调用是个好主意吗?

Example:例子:

async continueWork(){

   if(!this.list.length)
     return;

   var next = this.list.shift();

   // do things with next

   await this.continueWork();
}

What happens if the list is very large?如果列表非常大,会发生什么? Can it cause problems?它会引起问题吗?

Yes, this can cause problems.是的,这可能会导致问题。 Each continueWork call is put onto the call stack, on top of the last continueWork , which can result in an overflow:每个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); });

You can fix it by await ing something inside continueWork before it recursively calls itself, so that the call stack doesn't pile up:您可以在continueWork递归调用自身之前通过await来修复它,这样调用堆栈就不会堆积:

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

The important thing is to ensure that there aren't a large number of synchronous function calls before the call stack empties.重要的是确保在调用堆栈清空之前没有大量的同步function 调用。 await (or .then ) ensures that what follows the await , or the .then callback, executes in a microtask (which will occur only after the call stack is clear). await (或.then )确保await.then回调之后的内容在微任务中执行(仅在调用堆栈清除后才会发生)。

why not use the good old while?为什么不使用旧时的好呢?

async continueWork(){
    while(this.list.length){
       let next = this.list.shift()
       await do_things_with_next(next)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM