Skip to content

The callback hell that never was

Let's talk about callbacks, people seem to get terrified by them, because they see something like this:

var mysql = require('mysql'),
    db = mysql.createClient({
        user: 'root',
        password: 'root'
    }),
    id = 1;

db.query('USE mydb', function (err) {
    //some code here
    db.query('SELECT * FROM whatever WHERE id=?', [id], function (err, foo) {
        if (foo) {
            //some other code
            db.query('UPDATE whatever SET bar=?', [foo.bar], function (err) {
                db.query('INSERT INTO someothertable (sometime) VALUES (NOW())', function () {
                    //some code
                    console.log("It's done");
                });
            });
        }
    });
    //more code
});

This has the potential to turn into hard to understand spaghetti code. But we don't have to write it like this, we don't have to inline every function we can simply name them instead.

var mysql = require('mysql'),
    db = mysql.createClient({
        user: 'root',
        password: 'root'
    }),
    id = 1;

function init(fn) {
    db.query('USE mydb', fn);
}

function fetch(id, fn) {
    db.query('SELECT * FROM whatever WHERE id=?', [id], fn);
}

function checker(err, foo) {
    if (foo) {
        //some other code
        update(foo.bar);
    }
}

function update(bar) {
    db.query('UPDATE whatever SET bar=?', [bar], function (err) {
        db.query('INSERT INTO someothertable (sometime) VALUES (NOW())', function () {
            //some code
            console.log("It's done");
        });
    });
}

init(function () {
    fetch(id, checker);
})

We could also put this in a module or wrap a (pseudo) class around it if we wanted to. The main point is that we don't have to nest inline callbacks to get the job done, we can name them.