Docs

Everything You Need to Know

Promises

Use

ECMAScript 6 Promises provide the following interface:

  1. Promise
  2. Promise.then()
  3. Promise.resolve()
  4. Promise.reject()
  5. Promise.catch()
  6. Promise.race()
  7. Promise.all()

If you are familiar jQuery's Deferred object, this will not look too foreign. Except for the last two: race and all. These have no equivalent with typical deferreds. They are features specific to ECMAScript promises.

The Promise Interface

An ECMAScript 6 promise is created with the "new" keyword. This returns an instance of the Promise object.

var myPromise = new Promise();

When you create a promise, you can also provide a callback. This will be able to handle two arguments: resolve and reject:

var myPromise = new Promise(function(resolve, reject) {
  var value;
  // Do something to get value;
  // ...
  // Then test value to determine how to handle the promise:
  if (value === 'good') {
    resolve(value);
  } else {
    // When you reject the promise,
    // you also get the reason it failed,
    // which you can choose to output if you want:
    reject(reason);
  }
});

Then

Promises provide several methods allowing us to do useful things. The way you'll most like use promises is with the then method. This method can take up two two callbacks–one for success and one for failure.

// Create an instance of a promise:
var myPromise = new Promise(function(resolve, reject) {
  // Resolve the promise:
  resolve('Success!');
  // or reject it:
  // reject('Lost in Space!');
});
myPromise.then(function(value) {
  // Success:
  console.log(value);
},
// Opps! There was a problem:
function(reason) {
  console.log(reason);
});

As you can see in the above code, then can handle two callbacks, one for success and another optional one for failure. You can just provide a single callback to handle the success. That's up to you. If you want, you could return whatever value you get in your success callback, which allows you to chain a second function. Read the next part on Multiple Thens for more information.

Multiple Thens

The then method always returns a promsie. This means that you can chain multiple thens together. This allows you to break your code up into more logical blocks. This also helps you to avoid one of JavaScript development's worse patterns–the pyramid of doom–deeply nest series of callbacks.

var myPromise = new Promise(function(resolve, reject) {
  resolve(1);
});
myPromise.then(function(value) {
  console.log(value); // 1
  // Return the value:
  return value + 1;
})
.then(fuction(value) {
  console.log(value) // 2
})

Resolve

We can resolve a promise at any time using the resolve method on the static Promise object. Once we execute the resolve method, the promise is disposed of.

// Define an alias for the resolve callback:
var fulfill;
new Promise(function (resolve, reject) {
  fulfill = resolve;
}).then(function(value) {
  equal(value, 5, 'Promise fulfilled with Promise should resolve to actual value');
  start();
});
fulfill(Promise.resolve(5));

Reject

Like the resolve example above, we can similarly reject a promise using its method on the static Promise object. In this example we pass a value that gets returned with the rejection:

var fulfill;
new Promise(function (resolve, reject) {
  fulfill = resolve;
}).catch(function(value) {
  console.log(value);
});
fulfill(Promise.reject(5));

Catch

We can handle errors and exceptions using the catch method. This enables us to have a series of thens that only handle success situations. ECMAScript promise pass any exception along until their is some callback to handle it.

var myPromise = new Promise(function(resolve, reject) {
  resolve("Success!");
});
myPromise.then(function(value) {
  console.log(value); // Success!
  throw "Oops! Something went wrong.";
})
.catch(function(error) {
  console.log(error); // Oops! Something went wrong.
})

Race

Sometimes you may need to execute several operations and any one of them could finish first. You want to take the result of the first to finishing, ignoring the others. ECMAScript promises enable this with the race method. This expects an array of promises as its argument.

var f1, f2, f3;
var p1 = new Promise(function(f, r) { f1 = f; });
var p2 = new Promise(function(f, r) { f2 = f; });
var p3 = new Promise(function(f, r) { f3 = f; });
Promise.race([p1, p2, p3]).then(function(value) {
  console.log('Promise.race() should resolve to: ' + value);
});
// Execute the second:
f2(2);

All

Unlike with race conditions, sometimes you want to execute a number of things and wait until they are all done before doing anything. In those cases you can use the all method. This expects an array of promises as its argument.

var f1, f2, f3;
var p1 = new Promise(function(f, r) { f1 = f; });
var p2 = new Promise(function(f, r) { f2 = f; });
var p3 = new Promise(function(f, r) { f3 = f; });
Promise.all([p1, p2, p3])
.then(function(value) {
  console.log(value);
});
// Execute theme in opposite order:
f3(3);
f2(2);
f1(1);