Skip to main content

Take Better Control of Your Code Using Javascript Promises

Jun 24 '15

javascript promises

Javascript Promises are nothing new. In fact frameworks like Angular.js and Ember.js have been using Promises for a while. Promises are becoming more and more popular—it even looks like promises are coming soon as a JavaScript standard (see here).

Up until a few months ago, I had never heard of a Promise. However, I have been working with them recently with Node.js and they have changed the way I write asynchronous code. Promises provide an alternative to asynchronous callbacks—they are essentially placeholders for future values that may or may not take some time to retrieve. Let’s take a look at what Promises JS can do for you.

Take this block of code for example. This is what a simple math problem would look like using a traditional callback structure (no Promises):

var addTwo = function (num, callback) {
	callback(null, num + 2);
};
 
addTwo(1, function(err, num1) {
	addTwo(num1, function(err, num2) {
		addTwo(num2, function(err, num3) {
			console.log(num3); // will print 7 in the console
		});
	});
});

Let’s take a look at the equivalent code with Promises (Using Node.js and bluebird as the Promise provider):

var Promise = require('bluebird');
 
var addTwoPromise = function(num) {
	return new Promise(function (fulfill, reject) {
		fulfill(num + 2);
	});
};
 
addTwoPromise(1)
.then(addTwoPromise)
.then(addTwoPromise)
.then(function(result) {
	console.log(result); // will print 7 in the console
});

Although this is a simple example, it shows what promises can do in terms of organizing your code. More complex code such as web service calls or database queries can also be adapted in order to use Javascript promises. That way, you can avoid some hard-to-read callback pyramid and handle all of your errors easily in one place. A more real world example might look something like this:

var Promise = require('bluebird');
 
var webCallPromise = function(params) {
	return new Promise(fulfill, reject)  {
		someWebCall( function (response, err) {
			if (err) {
				reject(err);
			} else {
				fulfill(response);
			}
		});		
	}
};
 
var databasePromise = function(params) {
	return new Promise(fulfill, reject) {
		doDbAction( function (results, err) {
			if (err) {
				reject(err);
			} else {
				fulfill(response);
			}
		});
	});
}
 
// Main Code
webCallPromise.then(function (response) {
	//web calll was good
	return databasePromise(response);
}.then(function (results) {
	// DB call was good
	// do something else if you like
}).catch(function (err) {
	// handle all errors here
});

In the above example, we have made some external web call and stored the result in some database. We didn’t need to use callbacks for the main execution and all of our errors will be caught in the .catch() method.

Promises are nice and I have barely even scratched the surface of how powerful they can be. They are excellent for allowing you to define the flow of your code. They allow you to daisy chain promises just like you could do with callbacks, but all error handling can still be done from a single .catch(). So the next time you are working on something that deals with asynchronous code, consider using Promises JS.

Read more about: