递归调用异步函数

mar*_*375 5 javascript stack-overflow recursion asynchronous node.js

我有一个异步函数,我想连续多次调用.问题是"多重"可能是几十万或几百万......

显而易见的方法是从回调中调用相同的函数,如:

function foo()
{
    asyncBar(foo);
}
Run Code Online (Sandbox Code Playgroud)

当然,还有一些逻辑可以阻止递归.问题是堆栈是否正在填充调用并且可能在某些时候导致堆栈溢出?

jfr*_*d00 9

问题是堆栈是否正在填充调用并且可能在某些时候导致堆栈溢出?

不. 如果asyncBar()调用回调它是异步传递的,那么就没有堆栈构建.

在你的代码中:

function foo() {
    asyncBar(foo);
}
Run Code Online (Sandbox Code Playgroud)

这是正在发生的事情,一步一步:

  1. 首先foo()叫.
  2. 然后调用asyncBar(foo).
  3. 因为它asyncBar是异步的,这意味着它启动一个异步操作(让我们假设它是一个http GET,但任何异步操作都可以).启动异步操作,但随后asyncBar()立即返回.
  4. foo()返回和堆栈的初始调用完全解开.有没有foo()在堆栈上了.
  5. 调用之后的任何代码都会foo()继续运行,直到完成并返回到事件循环.
  6. 同时异步操作将在未来完成一段时间.这会在事件队列中调用您的回调.
  7. 当JS引擎完成执行其他Javascript(这意味着堆栈完全为空)时,它会将该事件从事件队列中拉出并调用回调.
  8. 在这种情况下,回调函数是foo调用该函数并重新开始循环,直接返回到步骤2.

没有堆栈堆积.关键是异步回调在当前堆栈完成后被调用,解除并返回系统.