In my previous post I discussed how asynchronous (with callbacks) nature of Node.js is useful to develop non-blocking server side implementations. Let’s now see how async functions are developed with an example.
Async functions are typically developed with a single callback with result arguments and an optional error.
Here’s an example code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// defining a function | |
var async_factorial = function(n, callback){ | |
console.log("step1"); | |
var fact = 1; | |
process.nextTick(function(){ | |
for(var i=1; i<n; i++) { | |
fact = fact*i; | |
} | |
console.log("step2"); | |
callback(fact); | |
}); | |
}; | |
// using the function | |
async_factorial(50, function(result){ | |
console.log("step3"); | |
console.log("value is:" + result); | |
}); | |
console.log("Out of async"); |
Now if you run the above code as: node async.js the output is:
step1 Out of async step2 step3 value is:6.082818640342675e+62
Let’s explain what we did here:
We first define a function async_factorial with a callback. Inside async_factorial we do something interesting; we use process.nextTick. We know node runs an event loop and handle i/o operations asynchronously with the help of callback invocations. With process.nextTick, you register the supplied function or piece of code to be executed during the next iteration of event loop. Typically a queue of functions is maintained. So whenever the event loop is free from I/O events, it starts with the next tick or next loop, it then first checks for the queue and executes the functions in the queue and then checks for I/O events and continues the loop. Thus if you need to perform cpu intensive operation and at the same time don’t want to block any I/O event, you can use this trick to perform cpu operation in async way with callbacks using nextTick. This ensures that event loop is free and handle I/O as well. In this case, we process factorial(50) in async way with nextTick.
Execution flow:
1. On calling async_factorial the flow control reaches step1.
2. With process.nextTick we expect, calculation of factorial(50) happens in the next iteration event loop and only would the callback(fact) gets called.
3. Since async_factorial is waiting on callback for result, the next statement ‘Out of asyc’ gets executed in this iteration of event loop.
4. When the next event loop begins, the flow goes to step2, calculates factorial and returns the factorial value through callback
5. Since the result is now available the code inside async_factorial gets executed and we see step3 and value is:6.082818640342675e+62 being printed out.
Note: You could also use setTimeout instead of nextTick that provides you the option of setting the time to wait before performing operation. But as the documentation says, nextTick is more efficient.