将从回调中递归调用函数会导致堆栈溢出吗? [英] Will recursively calling a function from a callback cause a stack overflow?

查看:163
本文介绍了将从回调中递归调用函数会导致堆栈溢出吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to invoke a function after an event gets fired then in the same call back call the function again. This is to create a sort of event listener when the function completes.

当你看到代码时,你会知道我想要做什么:

You'll know what i'm trying to do when you see the code:

"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);
}); 



问题:



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

Question:

Could this potentially cause a stack overflow? Is there a way to refactor this code to not be recursive?

谢谢!

推荐答案


这可能导致堆栈溢出吗?

Could this potentially cause a stack overflow?

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

No, it will not cause a stack overflow. An async callback is called when the stack is completely unwound so there is no stack buildup.

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

Remember how an async operation works. The current thread of Javascript starts the async operation. That async operation is then managed by some other native code. The current thread of Javascript then runs to its completion and finishes (thus clearing the stack).

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

Some time later, the native code that is running the async operation sees that the operation has completed and posts an event to the Javascript event queue to call the callback for that async operation. When the JS engine is not running anything else, it will then pull that event out of the queue and process it (calling the callback). At the time it calls the callback, it will have an empty stack frame.

回调函数将有一个活动的作用域对象,但在Javascript作用域中是完全独立的来自堆栈框架。

There will be an active scope object for the callback function, but in Javascript scopes are completely separate from the stack frame.

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

The only time this could be a problem is if your callback was ever called synchronously. Then, there would obviously be a stack build-up and the potential for stack overflow. But, as long as the callback is always called asynchronously (which it should be), then there is no issue.


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

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

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

It is a very useful design pattern in Javascript asynchronous programming to run the next iteration of something from the completion of the previous iteration and calling a function from within it is the usual way to do so. There is no reason to refactor it.

这篇关于将从回调中递归调用函数会导致堆栈溢出吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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