JavaScript Promises for Dummies

Javascript Promises are not difficult. However, lots of people find it a little bit hard to understand at the beginning. Therefore, I would like to write down the way I understand promises, in a dummy way.

1. before asking Mom
2. Hey friend, I have a new black Samsung phone.
3. after asking mom

However, the actual output sequence is:

1. before asking Mom
2. after asking mom
3. Hey friend, I have a new black Samsung phone.

Why? Because life (or JS) waits for no man.

You, the kid, wouldn't stop playing while waiting for your mom promise (the new phone). Don't you? That's something we call asynchronous, the code will run without blocking or waiting for the result. Anything that need to wait for promise to proceed, you put that in .then.

ES5 - Majority browsers

The demo code is workable in ES5 environments (all major browsers + NodeJs) if you include Bluebird promise library. It's because ES5 doesn't support promises out of the box. Another famous promise library is Q by Kris Kowal.

ES6 / ES2015 - Modern browsers, NodeJs v6

The demo code works out of the box because ES6 supports promises natively. In addition, with ES6 functions, we can further simplify the code with fat arrow => and use const and let.

Normal Function to Add Two Numbers

Async Function to Add Two numbers

// add two numbers remotely// get the result by calling an APIconst result =getAddResultFromServer('http://www.example.com?num1=1&num2=2');// you get result = "undefined"

If you add the numbers with normal function, you get the result immediately. However when you issue a remote call to get result, you need to wait, you can't get the result immediately.

Or put it this way, you don't know if you will get the result because the server might be down, slow in response, etc. You don't want your entire process to be blocked while waiting for the result.

Calling APIs, downloading files, reading files are among some of the usual async operations that you'll perform.

World Before Promises: Callback

Must we use promise for asynchronous call? Nope. Prior to Promise, we use callback. Callback is just a function you call when you get the return result. Let's modify the previous example to accept a callback.

// add two numbers remotely// get the result by calling an APIfunctionaddAsync(num1, num2, callback){// use the famous jQuery getJSON callback APIreturn $.getJSON('http://www.example.com',{
num1: num1,
num2: num2
}, callback);}addAsync(1,2, success =>{// callbackconst result = success;// you get result = 3 here});

The syntax looks ok, why do we need promises then?

What if You Want to Perform Subsequent Async Action?

Let's say, instead of just add the numbers one time, we want to add 3 times. In a normal function, we do this:-

The syntax is less user friendly. In a nicer term, It looks like a pyramid, but people usually refer this as "callback hell", because the callback nested into another callback. Imagine you have 10 callbacks, your code will nested 10 times!

Escape From Callback Hell

Promises come in to rescue. Let's look at the promise version of the same example.

With promises, we flatten the callback with .then. In a way, it looks cleaner because of no callback nesting. Of course, with ES7 async syntax, we can even further enhance this example, but I leave that to you. :)