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

Ric*_*ler 7 javascript 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);
}); 
Run Code Online (Sandbox Code Playgroud)

题:

这可能导致堆栈溢出吗?有没有办法重构这段代码不是递归的?

谢谢!

jfr*_*d00 6

这可能导致堆栈溢出吗?

不,它不会导致堆栈溢出.当堆栈完全展开时调用异步回调,因此没有堆栈堆积.

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

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

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

唯一一次这可能是一个问题,如果您的回调被同步调用.然后,显然会出现堆栈堆积和堆栈溢出的可能性.但是,只要回调总是异步调用(它应该是),那么就没有问题.

有没有办法重构这段代码不是递归的?

它是Javascript异步编程中非常有用的设计模式,用于从上一次迭代完成后运行下一次迭代,并从中调用函数是通常的方法.没有理由重构它.