Last Updated: September 30, 2021
· Evgenia Karunus

Js promise chaining: order of execution

This article may be useful for you, if:

  • you have a basic understanding of ES6 promises,
  • but you have some doubts on how promise chaining works.

Promise.resolve() shorthand notation

const hi = Promise.resolve(6) 

is the same as

const hi = new Promise((resolve, reject) => {

And we can access 6 with hi.then((value_6)) now.

Order of promise execution

While higher promises get executed, promises that are located lower (not yet created with new Promise/Promise.resolve) are in the pending state.

Lower thens and catches start execution as soon as the promise they are fed (return value of another promise, eg Promise.resolve(1), Promise.resolve(2)) gets resolved or rejected.

    .then(() => {
    return Promise.resolve(2); 
   // when we arrive to this line, const hi = Promise.resolve(2) promise starts execution. 
   // when :hi is resolved, all thens, that are attached to it, - get fired. 
   // in our case, only the next :then is attached. 
   // If :hi got rejected, the closest :catch would get fired.
}).then((value) => {
    console.log(value) //=> 2
    return Promise.reject(3)
}).then(() => {
    // is never executed
}).catch((value) => {
    console.log(value) //=> 3
    return Promise.reject(4)
}).catch((value) => {
    console.log(value) //=> 4
    return 5 // same as Promise.resolve(5)
}).then((value) => {
    console.log(value) //=> 5
    // notice we returned nothing. same as Promise.resolve(undefined)
}).then((value) => {
    console.log(value) //=> undefined

Real-world example

  .then((response) => {
    return response.json(); // converting response to json take some time too, so they made it a promise (so that other code of ours isn't stuck waiting for json convertion). so we are returning a promse.
}).then((jsonedResponse) => {
    console.log(jsonedResponse); // { data: 'someData' }
}).catch((error) => {
    // this catch will get executed if either fetch() or json() promises get rejected. 
    // if we wanted to handle fetch() and json() promise rejections separately, we would place two cathes, with first one coming after fetch().

Some other resources

  • ES6 Promises in Depth > Note that where you tack your reactions onto matters.
  • Dynamic promise chains > Here is the thing: A promise function, and its .then statements all return promises. Duh, right? But the thing to note is that they return the most recent promise.