ES6 - Promises

Promise is a very common Latin word means guarantee or assurance of something. So how this thing is related to a Javascript (to a programming language) now?

Well the TC39 ( Technical Committee 39 making standards for EcmaScript) have introduced a built in way, to provide assurance of a value being returned/evaluated for asynchronous operations and named this construct as Promise. (NOTE: Promises are not a new construct, it's a well estaiblished design pattern being used by other js libs like Jquery, angular etc from quite a long time, just es6 provides a native implementation of it).

What is need for Promises ?

Well very simple to remove the issue of deep nesting of callback functions which generally occurs when we require to perform certain asynchronous operations in a sequence one after the another. Just for the sake of simplicity I am assuming a sitution where one gives request for login/signup and immediately after it, needs to compute hashkey for the current session if the user is logged in only.

Take a look at callback based code

const request = require('require'); // Assuming require is some module like XMLHttpRequest for sake of simplicity.

request.body = {
	username,
	password
};


request('www.somesite.com/login', (err, res) => {
	if (res) {
    const id = res.userId;
    request('www.somesite.com/compute?id=${id}',(err,res) => {
      if(res) {
        console.log("HASH KEY COMPUTED");
        
        // Now this can quickly become even more levels deep
        // once we have other operations to perform and can become
        // bit cumbersome to manage.
      }
    });
  }
});

Now lets take a look at promised version of the same idea

const request = require('require'); // Assuming require is some module like XMLHttpRequest for sake.

request.body = {
	username,
	password
};

request('www.somesite.com/login')
	.then(res=> {
		if (res) {
			const id = res.userId;
			return request('www.somesite.com/compute?id=${id}');
		}
	})
	.then(res => {
		if (res) {
			console.log('HASH KEY COMPUTED');
			// Now even this becomes complex, we can easily manage it
		}
	})
	.catch(err => {
		console.error(err.message);
	}); 
// Bonus option provides so easy error handling as well

so one can imagine the deep nesting of callbacks are hard to manage in case the sequence of operations are multiple levels deep.

Creating & Using Promise

We can create a promise , we need to use Promise constructor. We pass a function to the promise constructor also known as executor function which is executed immediately by promise constructor ( even before returning the object) and we need to provide the callback functions resolve and reject to let it handle both the cases in which promise is fullfilled and failed.

const promisedFunction = new Promise((resolve, reject) => {
	doSomeComputation(err, res => {
    if (res) {
      resolve(res);
    } else {
      reject('The promise just failed');
    }
  })
});

In order to consume the above Promise, we need to create we have to use the then construct and we can use the optional catch construct for catching error.

promisedFunction
	.then((res) => {
		// do some stuff when promise is resolved.
	})
	.catch((err) => {
		// do some stuff when error occurs.
	});

Conclusion

I tried to cover quite basics of Promise API, like what is need of promises and how to create and use promises. There are lot more technical details regarding promises which is being covered in the specs. I highly recommend visiting specs specs for details.