NodeJS Timers

Home / NodeJS Timers

NodeJS Timers

December 9, 2015 | Article | No Comments

A timer is a specialized type of clock for measuring time intervals. It is used for deploying routine action.

Node implements the timers API which also found in web browsers.

setTimeout

setTimeout let us to schedule an arbitrary function to be executed in the future. For example:

var timeout = 2000;    // 2 seconds
setTimeout(function() {
    console.log('time out!');
}, timeout);

The code above will register a function to be called when the timeout expires. As in any place in JavaScript, we can pass in an inline function, the name of a function or a variable which value is a function.

If we set the timeout to be 0 (zero), the function we pass gets executed some time after the stack clears, but with no waiting. This can be used to, for instance schedule a function that does not need to be executed immediately. This was a trick sometimes used on browser JavaScript. Another alternative we can use is process.nextTick() which is more efficient.

clearTimeout

A timer schedule can be disabled after it is scheduled. To clear it, we need a timeout handle which is returned by function setTimeout.

var timeoutHandle = setTimeout(function() { 
    console.log('Groaaarrrr!!!');
}, 1000);
clearTimeout(timeoutHandle);

If you look carefully, the timeout will never execute because we clear it just after we set it.

Another example:

var timeoutA = setTimeout(function() {
    console.log('timeout A');
}, 2000);

var timeoutB = setTimeout(function() {
    console.log('timeout B');
    clearTimeout(timeoutA);
}, 1000);

Which timeoutA will never be executed.

There are two timers above, A with timeout 2 seconds and B with timeout 1 second. The timeoutB (which fires first) unschedule timeoutA so timeout never executes and the program exits right after the timeoutB is executed.

setInterval

Set interval is similar to set timeout, but schedules a given function to run every X seconds.

var period = 1000; // 1 second
var interval = setInterval(function() {
  console.log('tick');
}, period);

That code will indefinitely keep the console logging ‘tick’ unless we terminate Node.

clearInterval

To terminate schedule set by setInterval, the procedure we do is similar to what we did to setTimeout. We need interval handler returned by setInterval and do it like this:

var interval = setInterval(...);
clearInterval(interval);

process.nextTick

A callback function can also be scheduled to run on next run of the event loop. To do so, we use:

process.nextTick(function() {
    // This runs on the next event loop
    console.log('yay!');
});

This method is preferred to setTimeout(fn, 0) because it is more efficient.

On each loop, the event loop executes the queued I/O events sequentially by calling associated callbacks. If, on any of the callbacks you take too long, the event loop won’t be processing other pending I/O events meanwhile (blocking). This can lead to waiting customers or tasks. When executing something that may take too long, we can delay execution until the next event loop, so waiting events will be processed meanwhile. It’s like going to the back of the line on a waiting line.

To escape the current event loop, we can use process.nextTick() like this:

process.nextTick(function() {
    // do something
});

This will delay processing that is not necessary to do immediately to the next event loop.

For instance, we need to remove a file, but perhaps we don’t need to do it before replying to the client. So we could do something like this:

stream.on('data', funciton(data) {
    stream.end('my response');
    process.nextTick(function() {
        fs.unlink('path/to/file');
    });
});

Let’s say we want to schedule a function that does some I/O – like parsing a log file -to execute periodically, and we want to guarantee that no two of those functions are executing at the same time. The best way is not to use a setInterval, since we don’t have that guarantee. the interval will fire no matter if the function has finished it’s duty or not.

Supposing there is an asynchronous function called “async” that performs some IO and that gets a callback to be invoked when finished, and we want to call it every second:

var interval = 1000;
setInterval(function() {
    async(function() {
        console.log('async is done');
    }
}, interval);

If any two async() calls can’t overlap, it is better off using tail recursion like this:

var interval = 1000;
(function schedule() {
    setTimeout(function() {
        async(function() {
            console.log('async is done!');
            schedule();
        });
    }, interval);
})();

Here we declare schedule() and invoking it immediately after we are declaring it.

This function schedules another function to execute within one second. The other function will then call async() and only when async is done we schedule a new one by calling schedul() again, this time inside the schedule function. This way we can be sure that no two calls to async execute simultaneously in this context.

The difference is that we probably won’t have async called every second (unless async takes to time to execute), but we will have it called 1 second after the last one finished.

, ,

About Author

about author

xathrya

A man who is obsessed to low level technology.

Leave a Reply

Your email address will not be published. Required fields are marked *

Social media & sharing icons powered by UltimatelySocial