简体   繁体   中英

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?

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:

 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:

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

why not use the good old while?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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