As we all know, JS is a single threaded language. Single threading is execution from the top down, synchronous execution, depending on the order of the code. The asynchronism involved in the business was initially solved by using callback functions and events, but this created a problem called callback hell (i.e. callback function callback, callback multiple times….). . Es6 then provides an object called Promise to solve this problem.

I won’t elaborate on promise here, but if it’s not clear, you can go to es6.ruanyifeng.com/?search=%3F…

1. Promise. The use of the all

Promise.all() : takes an array of arguments that wrap multiple Promise instances into a new Promise instance.

const myPromiseAll = Promise.all([p1,p2,p3]);
Copy the code

The state of a newly created instance (myPromiseAll) is determined by incoming P1, P2, and P3, which is simply the slowest. Resolved state: P1, P2 and P3 are all completed and in resolved state. && Reject: P1, P2, P3 If one of them is reject, reject is returned, regardless of whether the others are complete. ||

2. Manually implement a promise.all

Step 1: Pass in the array and wrap it as a new Promise instance

function myPromiseAll(arr) {
  return new Promise((resolve, reject) = > {
    resolve('I fulfilled a Promise. All');
    // or
    // reject(" reject ~~~")
  });
}
// Test it
let resultTest1 = mypromise([]); // The array has no elements
resultTest1.then(
  (res) = > {
    console.log(res); // Print: I implemented a promise.all
  },
  (err) = > {
    console.log(err); });Copy the code

Step 2: Do the simple completed state first:

The return values of P1, P2, and p3 form an array that is passed to the callback function of the instance (resultTest1).

function mypromise(arr) {
  let resultArr = []
  return new Promise((resolve, reject) = > {

     resolve(resultArr);  // Pass an array
   
  });
}
Copy the code

The arR argument can be divided into two types: empty and resolve if the array is not empty.

function mypromise(arr) {
  let resultArr = []
  return new Promise((resolve, reject) = > {
       // The array is empty and resolve is resolved
        if(arr.length == 0) {
            resolve(arr);
        }
        resolve(resultArr);  // Pass an array}}); }Copy the code

When the array is not empty, it is divided into two types: pass in a PROMISE instance and pass in a non-Promise instance

function mypromise(arr) {
  let resultArr = []
  return new Promise((resolve, reject) = > {
    // The array is empty and resolve is resolved
    if(arr.length == 0) {
       resolve(arr);
     }
    // Iterate over the array passed in
    for(let i = 0; i < arr.length; i++) {
      // If it is an instance of Promise
      if(true) {
      // todo
      resolve(resultArr);   
      } else {
          resultArr.push(arr[i]);
          //todo
          resolve(resultArr);  // Return an array}}}); }Copy the code

This uses the then method to determine if there is a PROMISE instance, and returns the resolve state when all instances are complete

function mypromise(arr) {
  let resultArr = [];
  return new Promise((resolve, reject) = > {
    // The array is empty and resolve is resolved
    if (arr.length == 0) {
      resolve(arr);
    }
    // Iterate over the array passed in
    for (let i = 0; i < arr.length; i++) {
      // If it is an instance of Promise
      if (arr[i].then) {
        arr[i].then(value= >{
          console.log(value);
          resultArr[i]=value; // Write the promise object into the result array and ensure a one-to-one correspondence
        });
        // When all instances are complete, enter resolve;
        if(resultArr.length === arr.length) { resolve(resultArr); }}else {
        resultArr.push(arr[i]);
         // When all instances are complete, enter resolve;
        if(resultArr.length === arr.length) { resolve(resultArr); }}}}); }Copy the code

Test: The resolve case completes, followed by the reject case:

If one of the incoming promises is reject, promise.all returns the failed result to the failed state’s callback, regardless of whether the other promises have completed (instead of terminating).

It is recommended to use catch method to catch exceptions. It can catch errors in the execution of the previous THEN method, and it is closer to synchronous writing (try/catch).

If there is no callback that uses the catch method to specify error handling, the error thrown by the Promise object is not passed to the outer code, that is, there is no response

function mypromise(arr) {
  let resultArr = [];
  return new Promise((resolve, reject) = > {
    // The array is empty and resolve is resolved
    if (arr.length == 0) {
      resolve(arr);
    }
    // Iterate over the array passed in
    for (let i = 0; i < arr.length; i++) {
      // If it is an instance of Promise
      if (arr[i].then) {
        arr[i].then(value= > { 
           resultArr[i] = value; // Write the Promise object into the result array
        }).catch((err) = > console.log("At least one of them failed."));
        // When all instances are complete, enter resolve;
        if(resultArr.length === arr.length) { resolve(resultArr); }}else {
      // If it is not a PROMISE, convert it to a Promise object.
       Promise.resolve(arr[i]).then(o= > {
          resultArr[i] = o;
          if(resultArr.length === arr.length) { resolve(resultArr); }})}}}); }Copy the code

Test a wave:

Also, you don’t have to write reject in it, you can write it in the catch function that returns the instance.Resolve = ‘promise’; resolve = ‘promise’;

function myPromiseAll(arr) {
  let resultArr = [];
  return new Promise((resolve, reject) = > {
    if (arr.length === 0) {
      resolve(arr);
    }
    for (let i = 0; i < arr.length; i++) {
      Promise.resolve(arr[i]).then(o= > { 
        resultArr[i] = o;
        if(resultArr.length === arr.length) {
          resolve(resultArr)
        }
      }).catch(e= > reject(e))
    }
  });
}
Copy the code

Test the

The test code is:let test1 = new Promise((res) = > {
  setTimeout(res, 1000.'test1 resolve')});let testPromiseArr = myPromiseAll([1, test1, 2]).then(res= > console.log(res));

Copy the code

The following screenshot shows the execution result:The promise is passed in as empty…

ResultArr. Length: resolve(resultArr) {resultArr: resolve(resultArr)}} Solution: Add a manual counter that ends when it equals arr.length. The test code is still above, the test is successful.

The final code is:

function myPromiseAll(arr) {
  let resultArr = [];
  return new Promise((resolve) = > {
    if(arr.length === 0) {
      resolve(arr);
    }
    let count = 0;
    for(let i = 0; i < arr.length; i +=1) {
      Promise.resolve(arr[i]).then(value= > {
        resultArr[i] = value;
        if(++count === arr.length) {
          resolve(resultArr);
        }
      }).catch((err) = > console.log("PromiseAll is wrong",err)); }})}let test1 = new Promise((res) = > {
  setTimeout(res, 1000.'test1 resolve')})let test2 = new Promise((res) = > {
  setTimeout(res, 2000.'test2 resolve')})let test3 = new Promise((res) = > {
  setTimeout(res, 2000.'test3 resolve')})let testAll = myPromiseAll([test1, test2, test3]).then( value= > {
  console.log(value);
})
let testArr = myPromiseAll([1.2.3]).then(val= > {
  console.log(val)
})
let testPromiseArr = myPromiseAll([1, test1, 2]).then(res= > console.log(res));

Copy the code