Tuesday, October 7, 2014

Do you even Promise?


This post is a summary of a short presentation I gave a while ago at work. Its is a brief introduction to Promises in JavaScript. It doesn't explain the exact syntax or what Promise object is but rather what I consider as important advantage of using Promises over old callback approach and why every JS programmer should get familiar with this design pattern.

If you code JavaScript, sooner or later you will have to deal with asynchronous operations and callbacks. These callbacks as we know have its problems. You as a programmer often end up with code like that:

someAsyncOperation(function(data) {
    // do stuff
    // or something
    anotherAsyncOperation(function(data2) {
        // do stuff
        // or something
        andYetAnoterAsyncOperation(function(data3) {
            // do stuff
            // or something
            imRunningOutOfNamesAsyncOp(function(data4) {
                // do stuff
                thisSucksAsyncOp(function(data5) {
                    // do something
                    // or who cares now?
                });
            });
        });
    });
});


Pyramid of doom, callback hell, call it what you will. This is far from elegant solution and even though that above example is nicely indented and has hardly any actual code in it, it is already hard to read. Add some logic to it and you got yourself a mess. Trying to maintain it will be a pain and room for errors is enormous.

As ugly as it is, it’s not the main problem however. Look at the code below and try to guess what will be its output:

try
{
    setTimeout(function() {
        throw new Error(“BOOM”);
    }, 2000);
} catch (ex)
{
    console.log(ex);
}

This illustrates main problem with vanilla JS callback approach. The Error thrown inside of callback will not be caught inside of catch block. It will fail miserably. So will this code:

someAsyncOperation(function(data) {
    // do stuff
    // or something
    anotherAsyncOperation(function(data2) {
        // do stuff
        // or something
        throw new Error(“DOH!”);
        andYetAnoterAsyncOperation(function(data3) {
            // do stuff
            // or something
            imRunningOutOfNamesAsyncOp(function(data4) {
                // do stuff
                thisSucksAsyncOp(function(data5) {
                    // do something
                    // or who cares now?
                });
            });
        });
    });
});


Imagine this happening in your NodeJs code. It will very likely bring your process down. You can of course use domains or AFAIK depreceated process.on(“uncaughtException..) but there is a better way.

That's where Promises come in. It’s a design pattern that allows you to deal with callback hell and, most importantly, deal with exceptions. Imagine that instead of the mess above you can write code like this:

someAsyncOperation()
.then(function(data) {
    // do stuff
    return anotherAsyncOperation();
})
.then(function(data) {
    // do stuff
    return andYetAnoterAsyncOperation();
})
.then(function(data) {
    // do stuff
    return imRunningOutOfNamesAsyncOp();
})
.then(function(data) {
    // do stuff
    return thisSucksAsyncOp();
})
.catch(function(err) {
    console.log(err);
    return err;
});

Callback hell is no more and structure looks much more flatten and readable. Instead of nested callbacks, each .then(..) is executed only when previous one (returning a Promise) finishes. Top to bottom, very much like synchronous code. Also notice the catch block at the end of the chain. Readability is important of course, but the main point of using promises is the way it let us deal with exceptions. Exceptions will be caught in catch block and will let us recover gracefully. Without doubt this is most important point this design pattern delivers.

Now, this very simple example in no way covers everything you need to know about promises. I didn't even explain what the Promise object is, .then method and other details. I hope however it illustrates important point, that Promises allow us to deal with exceptions in an elegant way. This alone should interest you in Promises enough to google and experiment further. There are tons of articles available on the net. Google and try as its important to see for yourself how promises simplify development. If you are interested also have a look at my short presentation that is available here.