Process Functions Asynchronously with a Final Callback
Purpose and use case
Generally your functions are executed asynchronously with some exceptions, and the challenge for some is when you have a piece of code that can not be executed until previous functions are complete or data is returned.
So then why exactly would you want to process functions asynchronously with a final callback function, give me examples.
-
Let's say you have some database calls that are then combined into a single object which is then passed onto some functionality or client side component, your logic to do this would be the final callback where as all of the logic to get the different dependant data can freely execute asynchronously!
-
Perhaps your app will aggregate data from various API's, or the same API but needs to call it multiple times. Perhaps a good example is to gather recent tweets from 10 random accounts you are following and aggregating these into a single thread to be passed to a client side component to display the results.
Node Module async
This solution is actually so light and generic that it can work both in NodeJS and in the browser, doing exactly what it says on the box so to speak.
The code
Vanilla JavaScript
Lets take a look at the familiar vanilla JavaScript first;
function asyncProcess(array, callback) {
var completed = 0;
if (array.length === 0) {
callback(); // done immediately
}
for (var i = 0, len = array.length; i < len; i++) {
array[i](function () {
completed++;
if (completed === array.length) {
callback();
}
});
}
};
See, simple and functional.
Using It
At first you might think this problem would be hard to solve, trust me, it is not scary at all.
var funcArray = [
function first(callback){
//do stuff
callback();
},
function second(callback){
//do stuff
callback();
},
function third(callback){
//do stuff
callback();
}
],
Callback = function Callback(){
//final function
};
asyncProcess(funcArray,Callback);
Surprised? It is that simple!
NodeJS
How does it look in node? lets use a simple export
so that we can easily require
it as a dependency;
In a library/module script, let's call it async.js
;
exports.process = function process(array, callback) {
var completed = 0;
if (array.length === 0) {
callback(); // done immediately
}
for (var i = 0, len = array.length; i < len; i++) {
array[i](function () {
completed++;
if (completed === array.length) {
callback();
}
});
}
};
Using It
In a logic script, lets use server.js
;
var async = require('async'),
funcArray = [
function first(callback){
//do stuff
callback();
},
function second(callback){
//do stuff
callback();
},
function third(callback){
//do stuff
callback();
}
],
Callback = function Callback(){
//final function
};
async.process(funcArray,Callback);
Tip
Next time you're facing a problem relating to async and data, do what I do, make a written list of the process flow, then try to write a simple function to handle it. This way you remove application logic from the business process and your code stays clean.
Lastly, avoid nested Callbacks! Name your callbacks so they are traceable and pass the name as an argument instead of nesting your callbacks.
Enjoyed this?
If you made it here I would love to hear what you thought of the article.