0

Can't understand one thing. On server I have some process which runs forever in async mode. For example like this:

function loginf() {
  console.log(1+1);
  process.nextTick(loginf);
}
loginf();

Its recusrion, and as I understand it must cause stack overflow and(or) eat the memory. How to to do long running forever without memory leak in node.js? Is it possible?

user3003873
  • 543
  • 1
  • 4
  • 21

1 Answers1

5

If you want to do something repeatedly and you want to do it in a friendly way that leaves cycles for other events in your server to be processed, then the usual way to do that is with setInterval().

setInterval(function() {
    console.log("called");
}, 1000);

Repeatedly calling the same function like you are doing with process.nextTick() is not really recursion and does not lead to a stack overflow because the stack completely unwinds before the event queue calls the function the next time. It finishes the current path of execution and then calls the function you passed to nextTick().

Your choices for this type of operation are:

setInterval()
setTimeout()
setImmediate()
process.nextTick()

All three choices let the current thread of execution finish before calling the callback function so there is no stack build-up.

setInterval() uses a system timer set for some time in the future and allows all other events currently in the queue or in the queue before the timer time occurs to be serviced before calling the setInterval() callback. Use setInterval() when a time pause between calls to the callback is advisable and you want the callback called repeatedly over and over again.

setTimeout() uses a system timer set for some time in the future and allows all other events currently in the queue or in the queue before the timer time occurs to be serviced before calling the setTimeout() callback. You can use setTimeout() repeatedly (setting another timeout from each callback), though this is generally what setInterval() is designed for. setTimeout() in node.js does not follow the minimum time interval that browsers do, so setTimeout(fn, 1) will be called pretty quickly, though not as quickly as setImmediate() or process.nextTick() due to implementation differences.

setImmediate() runs as soon as other events that are currently in the event queue have all been serviced. This is thus "fair" to other events in the system. Note, this is more efficient that setTimeout(fn, 0); because it doesn't need to use a system timer, but is coded right into the event sub-system. Use this when you want the stack to unwind and you want other events already in the queue to get processed first, but you want the callback to run as soon as possible otherwise.

process.nextTick() runs as soon as the current thread of execution finishes (and the stack unwinds), but BEFORE any other events currently in the event queue. This is not "fair" and if you run something over and over with process.nextTick(), you will starve the system of processing other types of events. It can be used once to run something as soon as possible after the stack unwinds, but should not be used repeatedly over and over again.

Some useful references:

setImmediate vs. nextTick

Does Node.js enforce a minimum delay for setTimeout?

NodeJS - setTimeout(fn,0) vs setImmediate(fn)

setImmediate vs process.nextTick vs setTimeout

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • In this case there is no adding to stack next tick. Am I right? – user3003873 Nov 27 '15 at 22:32
  • @user3003873 - see the paragraph I added to my answer. There's no adding to the stack with `.nextTick()` either, but it does not leave as many opportunities for other events to run as `setInterval()` and will hog the CPU. `setImmediate()` is yet another option. See http://stackoverflow.com/questions/15349733/setimmediate-vs-nexttick for info on that. – jfriend00 Nov 27 '15 at 22:33
  • setInterval is the same way? No stack loading? – user3003873 Nov 27 '15 at 22:35
  • @user3003873 - all three options, `setInterval()`, `setImmediate()` and `process.nextTick()` let the current thread of execution finish before executing the callback so there is no stack build-up. – jfriend00 Nov 27 '15 at 22:36
  • @user3003873 - I added a lot more description of the options. Did this answer your question? – jfriend00 Nov 27 '15 at 23:27