Few things you need to know about Promise Chain in Javascript
Published: 2022-12-25 08:28:52

As we all know, one of the most significant features of promise is using the promise chain to replace the callback hell. That's awesome! And there are a few things you need to know about a promise chain to master it. Let's dive into it! 
<br>

At the beginning, we define **.then**, and **.finally** are the primary promise chain methods. But why **.catch** is not accounted? As it is the same as ***.then(null, onRejected)***
<br>

### 1. A ***pending*** promise can terminate the promise chain
A promise with pending state will not enter a promise chain and will not trigger any promise chain method.

```javascript
// Example 1
// Created a pending promise simply by doing nothing.
const pendingPromise = new Promise(()=>{})

// the following code will not be executed
pendingPromise.then(
  ()=>{
    console.log('onFulfilled')
  },
  ()=>{
   console.log('onRejected')
  }
)

// Example 2
const fulfilledPromise = Promise.resolve('success')

fulfilledPromise.then(
  () => {
  // execute here
  console.log('trigger 1st then')
  // break the promise chain
  return new Promise(()=>{})
  },
).then(
  () => {
  // this will not be executed
  console.log('trigger 2nd then') 
  }
).finally(()=>{
  // this will not be executed
  console.log('trigger finally') 
})

```


### <br>

### 2. After triggered ***.then***, promise state will become fulfilled by default.
If we do not throw errors or return rejected promise during the promise chain, it will return fulfilled promise after triggered any promise chain method.

```javascript
// Example 1
const rejectedPromise = Promise.reject('failed')
rejectedPromise.then(
  ()=>{
    console.log('onFulfilled, trigger 1st then ')
  },
  ()=>{
    // executed here
    console.log('onRejected, trigger 1st then')
  }
).then(
  ()=>{
    // executed here, as the promise state turned into fulfilled.
    console.log('onFulfilled, trigger 2nd then ')
  },
  ()=>{
    console.log('onRejected, trigger 2nd then ') 
  }
)

// Example 2
const fulfilledPromise = Promise.resolve('success')
fulfilledPromise.then(
  ()=>{
    // executed here
    console.log('onFulfilled, trigger 1st then ')
    throw new Error('failed')
  },
).catch(
  ()=>{
    // executed here, as the promise state turned into rejected
    console.log('onRejected, trigger catch') 
  }
).then(
  ()=>{
    // executed here, as the promise state turned into fulfilled.
    console.log('onFulfilled, trigger 2nd then ')
  },
  ()=>{
    console.log('onRejected, trigger 2nd then ') 
  }
)
```
### <br>
### 3. ***.finally*** is not actually final
After triggered the **.finally** method, we can still trigger **.then** or **.catch**, and the promise state keeps unchanged that is different from **.then** method
```javascript
// Example 1
const fulfilledPromise = Promise.resolve('success')
fulfilledPromise.then(
  ()=>{
   // execute here
   console.log('onFulfilled, trigger 1st then')
  }
).finally(()=>{
   // execute here
  console.log('trigger finally')
}).then(
  ()=>{
   // execute here
    console.log('onFulfilled, trigger 2nd then')
  }
)

// Example 2
const fulfilledPromise = Promise.resolve('success')
fulfilledPromise.then(
  ()=>{
   // execute here
   console.log('onFulfilled, trigger 1st then')
   throw new Error('failed')
  }
).finally(()=>{
   // execute here
  console.log('trigger finally')
}).then(
  ()=>{
    console.log('onFulfilled, trigger 2nd then')
  }
).catch(
  ()=>{
   // execute here
   console.log('onRejected, trigger catch')
  }
)
```