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.

  1. 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!

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

Subscribe to Christopher D. Langton

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe