Promise. The role of allsettled and how to realize promise by yourself allSettled

introduction

This paper introduces promise step by step from four aspects allSettled :

  • Promise. Defects of all()
  • Introduce promise allSettled()
  • Promise.allSettled() and promise All () respective applicable scenarios
  • Handwritten promise Settled() implementation

The following text begins 👇

Promise. Defects of all()

We have introduced it in a previous article when we use promise When all() has executed more than one promise, reject will be executed as long as any one of them fails, and the reject is the first error message thrown. It will be called only when all the {promise} are {resolve} Successful callback in then #

const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, 'three');
});

Promise.all([p1, p2, p3])
.then(values => {
    console.log('resolve: ', values)
}).catch(err => {
    console.log('reject: ', err)
})    

// reject:  three

Note: any promise is rejected All # will be rejected immediately, and other unfinished promises in the array are still being executed, promise No measures have been taken to cancel their implementation

However, in most scenarios, we expect the incoming group of promises to obtain the execution results of each promise regardless of whether the execution fails or succeeds. Therefore, promise is introduced in ES2020 allSettled()

Promise.allSettled()

Promise.allSettled() can get the result of each promise in the array, whether successful or failed

const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, 'three');
});

Promise.allSettled([p1, p2, p3])
.then(values => {
    console.log(values)
})    

/*
[
  {status: "fulfilled", value: 1}, 
  {status: "fulfilled", value: 2}, 
  {status: "rejected", reason: "three"}
]
*/

When the browser does not support promise Allsettled, you can polyfill as follows:

if (!Promise.allSettled) {
  const rejectHandler = reason => ({status: "rejected", reason})
  const resolveHandler = value => ({status: "fulfilled", value})
  Promise.allSettled = promises =>
    Promise.all(
      promises.map((promise) =>
        Promise.resolve(promise) 
          .then(resolveHandler, rejectHandler)
      )
      // Each promise requires promise Resolve package
      // To prevent non promise from being passed
    );
}

// use
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, 'three');
})
const promises = [p1, p2, p3]
Promise.allSettled(promises).then(console.log)

Promise.allSettled() and promise All () respective applicable scenarios

Promise.allSettled() is more suitable for:

  • They do not depend on each other. Any one of them is reject ed and has no impact on the others
  • Expect to know the execution result of each promise

Promise.all() is more suitable for:

  • They depend on each other. If any one of them is reject ed, the others will lose practical value

Handwritten promise Allsettled source code

With promise The difference is that when the promise is rejected, we will not reject it directly, but record the value of the reject and the corresponding state 'rejected';

Similarly, when the promise object is resolve d, we will not only record the value, but also record the state 'fully'.

When all promise objects have been executed (resolved or rejected), we uniformly resolve all promise execution result arrays

MyPromise.allSettled = function (promises) {
    return new MyPromise((resolve, reject) => {
      promises = Array.isArray(promises) ? promises : []
      let len = promises.length
      const argslen = len
      // If an empty array is passed in, a resolved empty array promise object is directly returned
      if (len === 0) return resolve([])
      // Convert the passed in parameters into an array and assign them to the args variable
      let args = Array.prototype.slice.call(promises)
      // Calculate whether all promise execution is completed, and then resolve
      const compute = () => {
        if(--len === 0) { 
          resolve(args)
        }
      }
      function resolvePromise(index, value) {
        // Judge whether the passed in is promise type
        if(value instanceof MyPromise) { 
          const then = value.then
          then.call(value, function(val) {
            args[index] = { status: 'fulfilled', value: val}
            compute()
          }, function(e) {
            args[index] = { status: 'rejected', reason: e }
            compute()
          })
        } else {
          args[index] = { status: 'fulfilled', value: value}
          compute()
        }
      }

      for(let i = 0; i < argslen; i++){
        resolvePromise(i, args[i])
      }
    })
  }

summary

Mutual dependence, a failure all failure (none or all) with promise all ; Independent of each other, obtain each result with promise allSettled

last

This article starts from the "three minute learning front-end". Reply to "communication" and automatically join the front-end three minute advanced group. One programming algorithm interview question (including solutions) every day will help you become a better front-end developer!

Added by ingchun on Wed, 09 Feb 2022 07:44:00 +0200