Get rid of JavaScript callback hell

I’m always interested in IPOs because sometimes “normal” investors can benefit in investing in a stock a few days after the IPO.

There’s an “official” page which lists the upcoming IPO for each month; unfortunately there doesn’t exist a notification service for such data. A simple web scraper that stores extracted data on a persistent storage and broadcasts them with a popular service like Twitter could fill the gap.

I decided to implement this application in JavaScript because I was looking for an excuse to play with Javascript Promise API since they are a nice way to avoid JavaScript callback hell.

The application’s “core” looks really intuitive and clean:

loadPage(url)
    .then(parseRows)
    .then(connectDb)
    .then(setDb)
    .then(findStock)
    .then(tweetStock)
    .then(saveStock)
    .then(disconnectDb)
    .catch(function(e) {
        winston.error(e)
        process.exit(1)
    })

while the counterpart based exclusively on callbacks could be really a mess.

The loadPage function returns a Promise object that will be resolved or reject when the page will be loaded and parsed using cheerio. Then it’s followed by a sequence of then functions that takes the next task to do if loadPage’s promise will be fulfilled or a function that handles the error in case of rejection.

It’s quite straightforward to convert a callback based API in order to use promises. Below you can see the code required to insert a stock object on MongoDB.

function(stock) {
    var coll = db.collection(collName)
    var promise = new Promise(function(resolve, reject) {
        coll.insert(stock, function(err, res) {
            if (err !== null) {
                reject(new Error(err))
            } else {
                resolve(stock)
            }
        })
    })
    return promise
}

Initially, it could be a little mind-bending to use promises if you are heavily used to writing nested callbacks, but I think that it pays in terms of readability.

You can find the complete source code here and if you are interested like me in the latest news about IPOs you can follow @UPComingIPO’s tweets.

Written on June 11, 2015