从回调中递归调用函数会导致堆栈溢出吗?

Will recursively calling a function from a callback cause a stack overflow?

我想在触发事件后调用一个函数,然后在同一个回调中再次调用该函数。这是为了在函数完成时创建一种事件侦听器。

看到代码你就知道我在做什么了:

"use strict";
var page = require('webpage').create();
var system = require('system');

function onStdReadLine(callback) {
    system.stdin.readLineAsync(function(err, line) {
        callback(line);
        onStdReadLine(callback);
    });
}

onStdReadLine(function(line) {
    // do something when the line comes in
    system.stdout.writeLine(line);
}); 

问题:

这会不会导致堆栈溢出?有没有办法重构此代码使其不递归?

谢谢!

Could this potentially cause a stack overflow?

不会,不会造成堆栈溢出。当堆栈完全展开时调用异步回调,因此没有堆栈堆积。

记住异步操作是如何工作的。 Javascript 的当前线程启动异步操作。然后,该异步操作由其他一些本机代码管理。 Javascript 的当前线程然后 运行s 完成并结束(从而清除堆栈)。

一段时间后,运行执行异步操作的本机代码发现操作已完成,并向 Javascript 事件队列发送一个事件以调用该异步操作的回调.当 JS 引擎没有 运行ning 其他任何东西时,它会将该事件从队列中拉出并处理它(调用回调)。在它调用回调时,它将有一个空的堆栈框架。

回调函数将有一个活动范围对象,但在 Javascript 中,范围与堆栈框架完全分开。

唯一可能出现问题的情况是您的回调是否曾被同步调用过。然后,显然会出现堆栈堆积和堆栈溢出的可能性。但是,只要回调总是被异步调用(它应该是),就没有问题。

Is there a way to refactor this code to not be recursive?

在 Javascript 异步编程中,这是一个非常有用的设计模式 运行 从上一次迭代完成的某些东西的下一次迭代,并从其中调用函数是通常的方法这样做。没有理由重构它。

不,这不会导致堆栈溢出。当你调用一个异步函数时,原来的函数returns,所以它的栈帧被释放了。回调函数是从事件处理程序调用的,而不是从原始函数调用的。