Making (JavaScript) Promises

5 min read.

When writing JavaScript code you often, if not always, end up writing something that is asynchronous. Whether it’s responding to File I/O, a AJAX request using or user interaction the standard method have been to use callback functions. Writing a function that use callbacks can look something like the following

function fetchData(url, callback) {
	if(typeof callback !== "function") {
    	return; //don't do anything if the callback is undefined

    // code for fetching the data


var url = '...';

fetchData(url, function(data) {
	// Callback function.
    // do something with data when finished fetching it.

This works well and all up to a point when you start having multiple asynchronous functions that depends on the result of each other, which means we want to make them synchronously. As a worse case scenario, with callbacks, we could end up with something like the following

var url1 = '...';
var url2 = '...';
var url3 = '...';
var url4 = '...';

fetchData(url1, function(data1) {
	// Handle data from first call

	fetchData(url2, function(data2) {
    	// Handle data from second call

        fetchData(url3, function(data3) {
        	// Handle data from third call

            fetchData(url4, function(data4) {
            	// Handle data from fourth call

The problem with nestling functions like this is that over time the code will become harder and harder to understand. There are some ways you can refactor your code to avoid this phenomena called Callback Hell. One of them is using Promises.

The different forms of Promises

As of now, Promises comes in many different forms. However, in the next version of JavaScript, EcmaScript6, Promises will also be implemented natively.

Writing native promises

The basic structure for creating a promise is the following

var promise = new Promise(function(resolve, reject) {
	// Do something async

    if(/* everything with ok */) {
    	resolve(/* Message or data */);
    } else {
    	reject(/* Message or data */);

The Constructor for creating a Promise takes a Callback function with two parameters. These are used to either successfully resolve the promise or reject the promise if the operation performed in the callback fails.

When the promise have been created it can be used as following

	.then(function success(data) {
    	// Handle the success.
    }, function error(data) {
    	// Handle the error.

The promise contains a function called then, this functions takes two callbacks, one for handling a success and one for handling an error.

The promise also contains a function called catch. This function can be used as a substitute for using the error callback in the then function.

Promises can also be chained together. It looks something like this

var promise1 = ...;
var promise2 = ...;
var promise3 = ...;
var promise4 = ...;

    	return promise2;
    	return promise3;
    	return promise4;
    	// Handle error.

Above we defined 4 promises that perform some kind of async tasks. Each task is then executed synchronously and we also use the catch function to handle any errors that each promise could produce.

However, it doesn’t necessarily need to be promises that you chain in the then statements. then can also be used for transforming data by just returning a new value in the callback function like this

var promise = new Promise(function(resolve){

    	return data + 1;
    	console.log(data) // 2

A real example

So how would you use this for real? well one example would be using it for AJAX requests fetching JSON

function fetch(url) {
	return new Promise(function(resolve, reject){
    	var request = new XMLHttpRequest();'GET', url);

        request.onload = function() {
          if (req.status == 200) {
          else {

        request.onerror = function() {
          reject("Network Error");

        // Make the request

var url = '';

// fetching one user.
    	return JSON.parse(res);
    	console.log("user: ", jsonRes);
    .catch(function(err) {
    	console.log("error: ", err);

// fetching multiple users. using Promise.all
var user1 = fetch(url);
var user2 = fetch(url);
var user3 = fetch(url);

Promise.all([user1, user2, user3])
    	//returns first user
    .catch(function(err) {
    	console.log("error: ", err);

You can also find the code here.

Browser Support

As of writing this, the support for native Promises is the following


For desktop browsers it’s currently supported in Chrome (ver. 32), Firefox (ver. 29), IE11, Opera (ver. 19) and Safari (ver. 7.1).


On mobile the support is less extensive. Only Firefox Mobile (ver. 29), Chrome for Android (ver. 32) and Mobile Safari (ver. 8) supports native Promises.

If you want to support more browsers you need to either use one of the libraries mentioned earlier or use a polyfill.

More Reading

There are a lot of good articles out there that this post has taken inspirations from.

The libraries mentioned earlier, as well as the native implementation of Promises are based on the Promises/A+ spec.

There is quite good documentation and Browser Support Information available over at the Mozilla Developer Network.

Jake Archibald have written an extensive post on the subject.

Also, Last week the new Fetch API was introduced into Chrome (ver 40) that is a nice substitute for XMLHttpRequest. Fetch also uses promises.

comments powered by Disqus