Javascript promises tutorial – The Future of Async code with ES6 and How they are more than just Pretty Callbacks

javascript promises are the new way of handling complex asynchronous code in ES6. There have been many libraries before (like async in node) that were used for that goal, but now promises are native to javascript.

In this post I will show you a promise example. If you're on the back end with node 4.0+ you will be able to use them. In the front end, you will have to do a bit of tweaking before being able to use javascript promises. I have written a tutorial on how to use ES6 right now through tools like browserify and babel. You can also use jsfiddle, which now supports javascript 6 by choosing 'babel' as the compiler.

promises example:

You can follow along with this jsfiddle, just open your console and run the example.
// ES6 Promise Example

// server
// -----------------------------------------------------
// Imagine this array lives in your server
const people = [
	{name: 'John Doe', age: '30'},
	{name: 'Jane Doe', age: '24'}
];

// client
// -----------------------------------------------------

// function that simulates an AJAX call to our
// imaginary server, where the people array lives.
// The call may succeed or fail.
const simulateAJAXCall = (index, cb) => {
	let chance = Math.random();
	let isSuccess= (chance <= 0.80) ? true : false;
	
	return setTimeout(() => {
		if (isSuccess) {
			return cb(people[index]);
		}
		else {
			return cb(null);
		}
	}, 1000)
}

// Function that returns a promise to search
// a person according to his index
const getPerson = (index) => {
	
	// The promise resolves if the data comes back
	// successfully and it rejects in case of an error
	return new Promise((resolve, reject) => {
		
		console.log('fetching person...');
		simulateAJAXCall(index, (data) => {
		
			if (data === null) {
				reject('Something went wrong!');
			}
			
			resolve(data);
		});
	});
}

// Call getPerson, which will return a promise.
// If the promise resolves, then log the person,
// if there's an error, it will go to the catch
// block and be handled there.
getPerson(1).then(person => {

	console.log(person);
}).catch(error => {

	console.log(error);
});


In this example I emulate a server-client connection. Imagine that the array 'people' lives on the server. To access it, I would need to make an ajax call, the perfect example for asynchronous code. I use a promise here to make that ajax call. getPerson is a function that returns a promise. Promises have two parameters: resolve, when you're promises are successful, or reject, when they weren't. In this case, if our call isn't succesful, we have to reject the promise. I have added a fake probability that the call to our imaginary server will fail, as to give me the chance to test the reject side of the promise. At the end, we call getPerson and pass it in the index of the person we want to retrieve. After that we plug in a .then. The 'then' method only runs when your promises are resolved. It gets the parameter you passed in when you resolved the promises, in this case, the person. This is what you have to wrap your mind around when using promises so I will repeat it: The then method only runs WHEN you RESOLVE the promise! In this case, when the ajax call is successful, the promise will resolve and pass in the person that was requested so we can do stuff with it, like log it to the console. Now, the catch method is similar, and you can plug it in after any then method. It only runs when you reject your promise, and it gets whatever parameter you pass it. Normally you pass in the error.

callbacks vs promises

Now how does this differ from callbacks? how does it differ from doing something like:
getPerson(1, person => {
    console.log(person);
});
It even looks prettier right? One of the things that made me choose promises over callbacks is you can chain promises. You can do something like this with promises:
getPerson(1).then(person => {

    console.log(person);
    return getPerson(0);
}).then(person => {

    console.log(person)
}).catch(error => {

    console.log(error);
});
See that? Try it out. If I want to make a promise, and then make another promise I can do so quite easily by just chaining then. This of course would be better shown with an example where the second promise depends on the result of the first one, but you get the idea. If you were to make the same example using callbacks, you could just define a callback inside the first callback, but then you enter callback hell, and things start looking ugly after the first nested callback. Promises bring in more than just the ability to chain though. the Promise object brings in awesome functionality like Promise.all where you can pass an array of promises and it will return the result of each in an array once all promises resolveCheck this out for more info. If you liked this post, consider subscribing to my blog in order to get notified whenever I publish another article. No spam!
[wp_email_capture_form]