◄︎ Gregor's Portfolio Site
29 Apr 2018

Javascript promises

Javascript promises are a way to control asynchronous communication within your code. Each promise is a placeholder for an eventual response. By using promises you can queue your code to only execute when the response is returned. This is useful when waiting on AJAX requests, reading content from a file, or performing computationally heavy calculations. In the past this functionality required third party libraries, like $.get in JQuery, but are now natively supported through ES6. In fact, if you use the fetch method , you’re already using promises.

Declaring a Promise Here’s a promise constructor:

let p = new Promise(function(resolve, reject) {
	if(/* success condition */) {
		resolve('Succeeded');
	}
	else {
		reject('Failed');
	}
});
let p = new Promise(function(resolve, reject) {
	if(/* success condition */) {
		resolve('Succeeded');
	}
	else {
		reject('Failed');
	}
});

A promise declaration takes two arguments, resolve and reject. Both are function calls and the response supplied to resolve() or reject() will be returned when the respective condition is met. Note, the reject argument is optional, but if it’s not provided the Promise will fail silently. To simulate a use case for a promise we’ll add a 1000ms timeout to a function:

let calculationPromise = new Promise((resolve, reject) => {
	setTimeout( () => {
		resolve(2+2); // Only sent is successful
		reject("Sorry, request failed"); // Only sent if failed
	}, 1000);
});

Our promise function can be invoked and our dependent code will wait until it receives a response before running:

calculationPromise.then((successResponse) => {
	console.log(`Value: ${successResponse}`);
});

.then() One benefit of Promises is the ability to chain as many .then()’s as necessary, each executing in order and queued util a response is received. Here’s a slightly more complex example:

View on JSFiddle

let calculationPromise = new Promise((resolve, reject) => {
  setTimeout(function(){
    resolve(2+2); // Only sent is successful
    reject("Sorry, request failed"); // Only sent if failed
  }, 1000);
});

calculationPromise.then((successResponse) => {
   return successResponse + 2;
}).then((successResponse) => {
  document.querySelector("#response").innerHTML = `Final Value: ${successResponse}`; // should be 6 if our promise is working 
})

.catch() Promise function calls can include a catch callback which is executed when the promise is rejected:

new Promise( (resolve, reject) => {
	setTimeout(function() { reject('Something went wrong...'); }, 1000);
})
.then( (response) => console.log('This will not show', response) )
.catch( (error) => console.log('Rejected:', error) );
Here’s a cleaner version of our first example. This is a structure I aim for in real projects:
let calculationPromise = new Promise((resolve, reject) => {
	setTimeout( () => {
		resolve(2+2);
	reject("Sorry, request failed");
}, 1000);calculationPromise
.then(addTwo())
.then(printData());let addTwo = (res) => res + 2;
let printData = (res) => console.log(res);

Promise.all Promises offer a special method which can be used if you need to trigger multiple calls but only want to respond when all of them are completed. The Promise.all method takes an array of promises and sends one callback once they are all resolved:

let firstPromise = fetch('/users.json');
let secondPromise = fetch('/assets.json');
Promise.all([firstPromise, secondPromise]).then( (response) => {
	console.log("All promises were successful")
}).catch( (error) => {
	console.log("There was an error");
});

Promises are flexible and useful part of Javascript. With modern browser usage growing every day, we can expect adoption to only increase in the future. Learn more about promises at MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise