Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

Thanks!

like image 710
Rico Kahler Avatar asked Jun 22 '16 15:06

Rico Kahler


2 Answers

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.

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).

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.

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?

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.

like image 83
jfriend00 Avatar answered Nov 11 '22 05:11

jfriend00


No, this won't cause a stack overflow. When you call an asynchronous function, the original function returns, so it's stack frame is freed. The callback function is called from the event handler, not from the original function.

like image 34
Barmar Avatar answered Nov 11 '22 07:11

Barmar