Categories:

JavaScript Kit > JavaScript Reference > Here

Promises Object

Last updated: Sept 29th, 2015

JavaScript Promises are a new addition to ECMAscript 6 that provides an intuitive, robust way to react to the completion or failure of asynchronous tasks. At the heart of JavaScript Promises is the Promise() constructor function:

var mypromise = new Promise(function(resolve, reject){
 // asynchronous code to run here
 // call resolve() to indicate task successfully completed
 // call reject() to indicate task has failed 
})

To detect for native support of JavaScript Promises, we can probe for the window.Promise object:

if (window.Promise){
 // call Promise constructor function
}

Native JavaScript Promises are supported in all modern browsers except IE, and in IE Edge Windows 10. For other browsers, we can use a Polyfill such as es6-promise.js.

The following is a simple example that incorporates JavaScript Promises into a preload image function to intuitively define what happens after the (un)successful loading of an image:

function getImage(url){
	return new Promise(function(resolve, reject){
		var img = new Image()
		img.onload = function(){
			resolve(url)
		}
		img.onerror = function(){
			reject(url)
		}
		img.src = url
	})
}

Sample call:

getImage('doggy.jpg').then(function(successurl){
	document.getElementById('doggyplayground').innerHTML = '<img src="' + successurl + '" />'
}).catch(function(errorurl){
	console.log('Error loading ' + errorurl)
})

Related Tutorials

Properties

Properties Description
length The number of constructor arguments of the Promise object, or 1.
prototype References the prototype of the Promise constructor function

Static Methods

The following static methods of the Promise object are accessed by calling Promise.method() directly, without instantiating the object first with new.

Methods Description
Promise.all(iterable) Returns a promise that's resolved when all of the promises represented by the iterable (array or array-like) object has been fulfilled. The following example uses the getImage() function at the very top to log all the images that were preloaded once the entire process has completed:
var doggies = ['dog1.png', 'dog2.png', 'dog3.png', 'dog4.png', 'dog5.png']
// call getImage on each array element and return array of promises:
var doggypromises = doggies.map(getImage)

Promise.all(doggypromises).then(function(urls){
	console.log("Images loaded: " + urls)
}).catch(function(urls){
	console.log("Error fetching some images: " + urls)
})

Promise.all() is an all or nothing proposition- if one of the promises inside the iterable fails to load, the promise returned by Promise.all() is rejected, and the catch() method added to it is called instead.

The then() and catch() methods following Promise.all() is passed an array of data returned by each resolve(data) or reject(data) method of each promise contained in the iterable.

Promise.race(iterable) Returns a promise that's resolved as soon as one of the promises inside the iterable is resolved or rejected, bypassing all of the remaining promise objects' states. The following example uses the getImage() function at the very top to log the first doggy image to preload (or fail to preload) out of two doggy images:
// call getImage() on two images and return array of promises:
var doggypromises = [getImage('dog1.png'), getImage('dog2.png')] 

Promise.race(doggypromises).then(function(url){
	console.log("First doggy to load: " + url)
}).catch(function(url){
	console.log("First doggy that failed to load: " + url)
})

The then() and catch() methods following Promise.race() is passed the data returned by the resolve(data) or reject(data) method of the promise that was resolved/rejected first.

Promise.reject(data) Returns a promise that's rejected to begin with. Executes the 2nd function passed into any then() method that follows it, or subsequent catch() method.
var rejection = Promise.reject("Amy")

rejection.then(
	function(data){
		// not executed
	},
	function(data){
		console.log(data + " rejected me!") // logs Amy rejected me!
	}
)

The above is identical to:

var rejection = Promise.reject("Amy")

rejection.catch(function(data){
	console.log(data + " rejected me!") // logs Amy rejected me!
})
Promise.resolve(data) Returns a promise that's resolved to begin with. You can use it to create a blank "canvas" in which to create a sequence of promises using. The following creates a new resolved promise and chains multiple then() methods to it to create a sequence of promises that are resolved sequentially:
var sequence = Promise.resolve()
var myarray = [1,2,3,4,5]

myarray.forEach(function(element){
	sequence = sequence.then(function(){
		var el = element
		return new Promise(function(resolve, reject){
			setTimeout(function(){
				resolve(el)
			}, 1000) // resolve each promise after 1 second
		})
	}).then(function(data){
		console.log(data) // logs 1,2,3,4,5 one number per second
	})
})

 

Instance Methods

The following instance methods are available on an instantiated Promise object, by calling new Promise().

Methods Description
Promise.catch(callback) Executes the callback function when a promise has been rejected. Same as calling Promise.then(undefined, callback).
Promise.then(resolvedcallback, rejectedcallback) Executes either the first or second callback function when a promise has either been resolved or rejected, respectively.

The following example uses the getImage() function at the very top of the page to perform two different actions based on whether an image has successfully loaded or not:

getImage('dog1.png').then(
	function(successurl){
		var dog = document.createElement('img')
		dog.setAttribute('src', successurl)
		document.body.appendChild(dog)
	},
	function(errorurl){
		console.log('Error loading ' + errorurl)
	}
)

Functionally this is similar to the following:

getImage('dog1.png').then(function(successurl){
	var dog = document.createElement('img')
	dog.setAttribute('src', successurl)
	document.body.appendChild(dog)
}).catch(function(errorurl){
	console.log('Error loading ' + errorurl)
})

Returning a value or promise inside the then() method

Inside a then() method, you can either return a value or another promise. In the case of the former, the return value is simply passed onto the next then() method added to the promise:

var p = new Promise(function(resolve, reject){
	resolve('Mary')
})

p.then(function(friend){
	console.log(friend) // logs "Mary"
	return 'John'
}).then(function(friend){
	console.log(friend) // logs "John"
})

However, if you return a promise inside then() instead of a static value, the next then() waits for the resolution of that promise before executing.

function stutter(name){
	return new Promise(function(resolve, reject){
		setTimeout(function(){ // delay resolution of promise
			resolve(name)
		}, 1000)
	})
}

var p = new Promise(function(resolve, reject){
	resolve('Mary')
})

p.then(function(friend){
	console.log(friend) // logs "Mary" immediately
	return stutter('John')
}).then(function(friend){
	console.log(friend) // logs "John" after 1 sec
	return stutter('George')
}).then(function(friend){
	console.log(friend) // logs "George" after 2 sec
})

Reference List

Right column

CopyRight (c) 2018 JavaScript Kit. NO PART may be reproduced without author's permission. Contact Info