17. Promises

ES6 has native support for promises. A promise is an object that is waiting for an asynchronous operation to complete, and when that operation completes, the promise is either fulfilled(resolved) or rejected.

The standard way to create a Promise is by using the new Promise() constructor which accepts a handler that is given two functions as parameters. The first handler (typically named resolve) is a function to call with the future value when it’s ready; and the second handler (typically named reject) is a function to call to reject the Promise if it can’t resolve the future value.

  1. const p = new Promise((resolve, reject) => {
  2. if (/* condition */) {
  3. resolve(/* value */); // fulfilled successfully
  4. } else {
  5. reject(/* reason */); // error, rejected
  6. }
  7. });

Every Promise has a method named then which takes a pair of callbacks. The first callback is called if the promise is resolved, while the second is called if the promise is rejected.

  1. p.then((val) => console.log("Promise Resolved", val),
  2. (err) => console.log("Promise Rejected", err));

Returning a value from then callbacks will pass the value to the next then callback.

  1. const hello = new Promise((resolve, reject) => { resolve("Hello") });
  2. hello.then((str) => `${str} World`)
  3. .then((str) => `${str}!`)
  4. .then((str) => console.log(str)) // Hello World!

When returning a promise, the resolved value of the promise will get passed to the next callback to effectively chain them together.
This is a simple technique to avoid “callback hell”.

  1. const p = new Promise((resolve, reject) => { resolve(1) });
  2. const eventuallyAdd1 = (val) => new Promise((resolve, reject) => { resolve(val + 1) });
  3. p.then(eventuallyAdd1)
  4. .then(eventuallyAdd1)
  5. .then((val) => console.log(val)); // 3