Promise chaining

suggest change

The then method of a promise returns a new promise.

const promise = new Promise(resolve => setTimeout(resolve, 5000));

promise
    // 5 seconds later
    .then(() => 2)
    // returning a value from a then callback will cause
    // the new promise to resolve with this value
    .then(value => { /* value === 2 */ });

Returning a Promise from a then callback will append it to the promise chain.

function wait(millis) {
    return new Promise(resolve => setTimeout(resolve, millis));
}

const p = wait(5000).then(() => wait(4000)).then(() => wait(1000));
p.then(() => { /* 10 seconds have passed */ });

A catch allows a rejected promise to recover, similar to how catch in a try/catch statement works. Any chained then after a catch will execute its resolve handler using the value resolved from the catch.

const p = new Promise(resolve => {throw 'oh no'});
p.catch(() => 'oh yes').then(console.log.bind(console));  // outputs "oh yes"

If there are no catch or reject handlers in the middle of the chain, a catch at the end will capture any rejection in the chain:

p.catch(() => Promise.reject('oh yes'))
  .then(console.log.bind(console))      // won't be called
  .catch(console.error.bind(console));  // outputs "oh yes"

On certain occasions, you may want to “branch” the execution of the functions. You can do it by returning different promises from a function depending on the condition. Later in the code, you can merge all of these branches into one to call other functions on them and/or to handle all errors in one place.

promise
    .then(result => {          
        if (result.condition) {
            return handlerFn1() 
                .then(handlerFn2);
        } else if (result.condition2) {
            return handlerFn3()
                .then(handlerFn4);
        } else {
            throw new Error("Invalid result");
        }
    })
    .then(handlerFn5)
    .catch(err => {
        console.error(err);
    });

Thus, the execution order of the functions looks like:

promise --> handlerFn1 -> handlerFn2 --> handlerFn5 ~~> .catch()
         |                            ^
         V                            |
         -> handlerFn3 -> handlerFn4 -^

The single catch will get the error on whichever branch it may occur.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Promises:
* Syntax
* Promise chaining

Table Of Contents
11 Arrays
12 Objects
14 Classes
16 Map
17 Set
24 Loops
27 Date
29 Scope
30 AJAX
31 Promises
35 Cookies
41 JSON
44 Fetch
45 Modules
46 Screen
64 Console
68 Symbols
73 Modals
76 Events
86 Proxy
89 WeakMap
90 WeakSet
102 Tilde