[英]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.