The same routine hand tear Promise all, allSettled, any, race method

Similarities and differences

Here’s what they have in common:

  1. Each of these methods takes an iterable input from a Promise.
  2. Each of these methods returns onePromiseInstance.

And look at the differences:

  1. The returned Promise instance changes state at different times
    • The All method performs its own resolve callback after all input Promise instances are resolve, and its own Reject callback after any input Promise instance reject.
    • The allSettled method executes its own resolve callback after all input Promise instances have changed state (perform a resolve or reject callback).
    • The any method executes its own Reject callback after all input Promise instances reject, and its own resolve callback after any input Promise instance resolve.
    • The RACE method changes itself in the same state after any input Promise instance changes state.
  2. Of the returned Promise instanceEventual or reasondifferent
    • The all method returns the final value of a Promise instance as an array whose members are the final values of all entered Promise instances and are sorted in the order in which they were promised, not in the order in which they were called. Rejection is the rejection of the first state in the entered Promise instance that changes to Rejected.
    • The final value of the Promise instance returned by the allSettled method is also an array, in the same order as the Promise input, where each member is entered with the Promise state as Resolved{status:' depressing ', value: the same final value}, is in the Rejected state{status:'rejected', reason: same rejected cause}.
  3. Returns different values when the argument is an empty iterator
    • The All method synchronously returns a Promise in the Resolved state with an empty array as the end value.
    • The allSettled method behaves the same as the ALL method.
    • The any method synchronously returns a promise with the Rejected state, whose rejection is aAggregateErrorObject.
    • The race method returns a promise that waits forever.

This is a horizontal comparison of the four All, allSettled, ANY, and RACE methods. If you want to view a description of one method in general, check out the resources at the end of this article.

The next step is implementation, but for simplicity we’ll only deal with arrays. The other iterable types (Set, Map, String, etc.) differ mainly in the number of members taken or the way they are iterated.

The first thing to deal with is that when the argument is an empty iterator, our template looks like this:

+function template(promises){
+ if(promises.length === 0){
+ // Handle it according to different circumstances
+}
+}
Copy the code

If the length of the argument is not empty, return a new Promise:

function template(promises){
    if(promises.length = = = 0) {}}+ return new Promise((resolve,reject) => {
+ // Handle according to different circumstances
+})
}
Copy the code

Define a result collection array and a variable that represents the number of promise states that meet the criteria:

function template(promises){
    if(promises.length = = = 0) {}}+ let result = [], num = 0;Return new Promise((resolve,reject) => {// resolve,reject)}Copy the code

We iterate through the parameters inside the returned Promise and add a then callback to it, which will be processed as needed. The final template looks like this:

function template(promises) {
  if (promises.length === 0) {
    // Handle it according to different circumstances
  }
  let result = [],
    num = 0
  return new Promise((resolve, reject) = > {
    const check = () = > {
      if (num === promises.length) {
        Call resolve or reject, depending on the case
      }
    }
    promises.forEach(item= > {
      Promise.resolve(item).then(
        res= > {
          // Process result, num, and resolve, reject, and check, depending on the case
        },
        err= > {
          // Process result, num, and resolve, reject, and check, depending on the case})})})}Copy the code

Resolve:

The promise.resolve (value) method returns a Promise object resolved with the given value. If the value is a Promise, the promise is returned; If the value is thenable (that is, with the “then” method), the returned promise “follows “the thenable object and adopts its final state; Otherwise the returned promise will be fulfilled with this value.

Resolve: Promises contain values that are not promises. Resolve will allow you to add then callbacks to promises.

The specific implementation

  1. All methods

    function all(promises) {
      if (promises.length === 0) return Promise.resolve([])
      return new Promise((resolve, reject) = > {
        let result = []
        let num = 0
        const check = () = > {
          if (num === promises.length) {
            resolve(result)
          }
        }
        promises.forEach((item, index) = > {
          Promise.resolve(item).then(
            res= > {
              result[index] = res
              num++
              check()
            },
            err= > {
              reject(err)
            }
          )
        })
      })
    }
    Copy the code
  2. AllSettled method

    function allSettled(promises) {
      if (promises.length === 0) return Promise.resolve([])
      return new Promise((resolve, reject) = > {
        let result = []
        let num = 0
        const check = () = > {
          if (num === promises.length) resolve(result)
        }
        promises.forEach((item, index) = > {
          Promise.resolve(item).then(
            res= > {
              result[index] = { status: 'fulfilled'.value: res }
              num++
              check()
            },
            err= > {
              result[index] = { status: 'rejected'.reason: err }
              num++
              check()
            }
          )
        })
      })
    }
    Copy the code
  3. Any way

    function any(promises) {
      if (promises.length === 0) {
        reject(new AggregateError('No Promise in Promise.any was resolved'))}return new Promise((resolve, reject) = > {
        let result = []
        let num = 0
        const check = () = > {
          if (num === promises.length) {
            reject(new AggregateError('No Promise in Promise.any was resolved'))
          }
        }
        promises.forEach((item, index) = > {
          Promise.resolve(item).then(
            res= > {
              resolve(res)
            },
            err= > {
              result[index] = err
              num++
              check()
            }
          )
        })
      })
    }
    Copy the code
  4. The Race method, compared to the other three methods, is a bit simpler to implement than the template

    function race(promises) {
      if (promises.length === 0) return Promise.resolve()
      return new Promise((resolve, reject) = > {
        promises.forEach(item= > {
          item.then(resolve, reject)
        })
      })
    }
    Copy the code

The resources

  1. MDN Promise.all()
  2. MDN Promise.allSettled()
  3. MDN Promise.any()
  4. MDN Promise.race()
  5. MDN Promise.resolve()