为什么无限递归异步函数不会导致堆栈溢出? [英] Why doesn't an infinitely recursive async function cause stack overflow?

查看:142
本文介绍了为什么无限递归异步函数不会导致堆栈溢出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在想,当异步函数递归地无限调用自己时会发生什么.我的想法是,它不会导致堆栈溢出.但是我无法确切指出为什么会这样.

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 awaited. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆