为什么无限递归异步函数不会导致堆栈溢出? [英] Why doesn't an infinitely recursive async function cause stack overflow?
问题描述
我在想,当异步函数递归地无限调用自己时会发生什么.我的想法是,它不会导致堆栈溢出.但是我无法确切指出为什么会这样.
I was thinking what happens when an async function recursively calls itself infinitely. My thought was that it will not cause stack overflow. But I can't exactly point out why this is the case.
const foo = async () => {
const txt = await Promise.resolve("foo");
console.log(txt);
foo();
}
foo();
上面的代码无限地打印"foo",而不会溢出堆栈.
The code above prints "foo" infinitely without overflowing the stack.
我的想法是代码在概念上与以下代码类似,它不会导致堆栈溢出,因为对 foo()
的递归调用位于回调内部,即对的原始调用foo()
将在此之前返回.
My idea is that the code is conceptually similar to the following, it doesn't cause stack overflow because the recursive call to foo()
is inside the callback, the original call to foo()
will return before that.
const bar = () => {
console.log("foo");
foo();
}
const foo = () => {
setImmediate(bar);
}
foo();
我正在寻找有关异步功能情况的确切答案.
I am looking for the exact answer as to what happens in the case of the async function.
推荐答案
您的代码不会产生堆栈溢出,因为当您在函数内调用 foo
时,它不是 await
ed.如果您编写 await foo();
,则应导致堆栈溢出.
Your code doesn't produce stack overflow because when you have call foo
inside function it is not await
ed. If you write await foo();
then it should cause stack overflow.
请考虑以下两种情况:
案例1 在这里根据您的代码.从 a()
它将调用 foo
,而无需 await
.因此,当它调用 foo()
(因为它是 async
函数)时会发生什么,它将安排在当前执行解析后运行.更确切地说,它将排队等待稍后执行,并且 a()
也将立即从下一行继续.您可以看到 a()
首先结束的输出,它不等待 foo
返回的调用堆栈;
Case 1
Here as per your code. From a()
it will call foo
without await
. So what will happen when it calls foo()
as it is async
function, it would be scheduled to run after the current execution resolves. Or even more precisely, it will be queued for later execution
and immediately a()
will also continue from next line. You can see the output that a()
is getting ended first, it doesn't wait for call stack for foo
to return;
const foo = async () => {
const txt = await Promise.resolve("foo");
console.log(txt);
}
const a = async () => {
const txt = await Promise.resolve("a");
console.log(txt);
foo();
console.log("-- ENd of a() --");
}
a();
案例2 在 a()
内部,它将使用 await
调用 foo
.您可以看到 a()
正在等待 foo()
返回的输出,然后只有它会在下一行继续.
Case 2
Here inside a()
it will call foo
with await
. You can see the output that a()
is waiting for return from foo()
then only it will continue on next line.
const foo = async () => {
const txt = await Promise.resolve("foo");
console.log(txt);
}
const a = async () => {
const txt = await Promise.resolve("a");
console.log(txt);
await foo();
console.log("-- ENd of a() --");
}
a();
这篇关于为什么无限递归异步函数不会导致堆栈溢出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!