const p = new Promise((resolve, reject) = > {
    resolve('ok')})const result = p.then((value) = > {
    return new Promise((resolve, reject) = > {
        // 1, return a successful promise
         //resolve('success')
        // 2, return failed promise
        reject('error')
    })
})
result
Copy the code

preface

Promise is ES6 introduced a new solution for asynchronous programming, in terms of grammar, it is a constructor that can encapsulate asynchronous tasks and can be processed with the results, its biggest advantage is that can solve the problem of asynchronous callback region, and it specifies a callback for error handling this to be more flexible and convenient. It is widely used in modern projects, whether web or APP projects. Promise can be seen on both the front and back ends. It’s also a popular question in modern interviews, so it’s important to understand how Promise works. If you still don’t know how to use Promise, check out Ruan yifeng’s ES6 Promise tutorial.

  • The introduction of Promise

understand

  1. Promise is the ES6 specification
  2. Promise is a JS solution for asynchronous programming (the old solution was a callback function) an asynchronous operation with success/failure results
Asynchronous programming (old scheme callback function) (1Fs file operationrequire(fs).readfile('.index.heml'.(err, data) = >({})2) Database operations (3)AJAX
$.get('server'.(data) = >({})4) the timersetTimeout(() = >{},0)
Copy the code
  1. Syntactically, it’s a constructor,
  2. Functionally,Promise objects are used to encapsulate and provide a unified interface that makes it easier to control asynchronous operations.
  3. Promise faults:
  • There is no way to cancel a Promise, which is executed as soon as it is created and cannot be cancelled halfway through.
  • Second, if you don’t set a callback function, errors thrown inside a Promise won’t be reflected externally.
  • When in a Pending state, there is no way to know what stage of progress is currently in (just started or about to be completed)

Characteristics of Promise

The state of the PromiseState object is not affected by the outside world. The Promise object represents an asynchronous operation with three states

  • Pending: Indicates the initial state, not the success or failure state.
  • Resolved/depressing: The operation is successful
  • Rejected: Indicates that the operation fails

Another property in the PromiseResult holds the result of the success/failure of the asynchronous task object

  • resolve
  • reject

3. Once the state changes, it never changes again. There are only two possibilities for the Promise object to change its state:

  • From the pending – > fulfilled
  • From the pending – > the rejected

Note: A Promise object can only be changed once, whether it succeeds or fails. The result of a success is usually called value, and the result of a failure is usually called Reason. Even if the result of a change has already occurred, adding a callback function to the Promise object will get the result immediately. This is completely different from events, which are characterized by the fact that if you miss it, you will not get the result if you listen again.

Why use Promise

  1. The way callback functions are specified is more flexible
  • Old, must be specified before starting asynchronous tasks
$.get('server'.(data) = > {
     // Execute the content
     // Specify the callback function first
})
Copy the code
  • Promise, start the asynchronous task => Return the Promise object => Bind the callback function to the Promise object (multiple can be specified after the asynchronous task ends)
 var p = new Promise((resolve, reject) = > {
            // Execute the content
            setTimeout(() = >{
                resolve('success')})})// Specify the callback function after starting the task
 p.then((val) = >{},(err) = > {})
 .then((val) = > {},(err) = >{})
 .then((val) = > {},(err) = >{})...Copy the code
  1. Support for chain calls to solve the problem of callback region
// Callback regiontest1(... arg1) =>{ test2(... arg2)=> { test3(... arg3) => {// More functions}}}Copy the code
  • Disadvantages of callback regions: not easy to read, not easy to handle exceptions
  • Resolve the callback region issue: Promise chain calls

Promise execution process

1. Basic execution diagram of Promise

  • The constructor is created, and the executer executes immediately and synchronously

2.Promise detailed execution flow chart (remarks,Resolved state is a very sad state)

 var p = new Promise ((resolved, rejected) = >{})
     p.then((onResolved, onRejected))
      .cacth(onRejected)
Copy the code

3.Promise Event polling execution diagram (only mentioned here, if you still don’t know about Event Loop Event polling, you can check it outThis article)

fn(resolve, reject)
var p = new Promise(fn)
var p' = p.then(onFufilled1, onRejected1)
var p" = p'.then(onFufilled2, onRejected2)
var p2 = new Promise(fn)
var p2' = p2.then(onFufilled1, onRejected1)
var p2" = p2'.then(onFufilled2, onRejected2)
Copy the code

Basic use of Promise

function rand (m, n) {
  return Math.ceil(Math.random()* (n-m+1)) + m-1;
}
/*Promise implementation * resolve * reject * reject * */
const p = new Promise(((resolve, reject) = > {
  setTimeout(() = > {
    const n = rand(1.100) // Get a random integer between 1 and 100
    if (n < 30) {
      resolve(n) // Set the Promise state to success
    } else {
      reject(n) // Set the Promise state to fail}},500)
}))
p.then((value) = > {
  console.log(value + 'This is 0 minus 30.')},(reason) = > {
  console.log(reason + 'This is the value between 30 and 90.')})Copy the code

Promise API

Promis constructor: Promise(executer){}

(1)execute (resolve, reject) =>{} (2) execute (resolve, reject) =>{} (3)reject: Executor also calls the Promise immediately and synchronously within the Promise, and asynchronous operations are performed in the executor

Prototype. Then (onResolved, onRejected) =>{}

(1) onResolved: Successful callback (value) =>{} (2) onRejected: failed callback (reason) =>{

3. Prototype. Catch method (onRejected) => {}

(1) then(undefined, onRejected) =>{}

4. Promise.resolve: (value) => {}

A function object belonging to a Promise, not an instance, returns a successful/failed Promise object

// If the argument passed is a non-PROMISE object, the result returned is a successful Promise object
// If the promise object is passed, the result of the argument determines the result of resolve
const p1 = Promise.resolve(521)
const p2 = Promise.resolve(new Promise((resolve,reject) = > {
    reject('failure')}))Copy the code

5. Promise. Reject method: (reject) => {}

(1) Return a failed promise object

// No matter what type of argument is passed, a failed Promise object is returned
const p1 = Promise.reject(521)
const p2 = Promise.reject(new Promise((resolve,reject) = > {
    resolve('success')}))// Handle the browser error
p1.catch((reason) = > {})
p2.catch((reason) = > {})
Copy the code

6. Promise. All methods: (promises) => {}

  • Promsies: An array of N Promises
  • Return a new promise
  • The status is returned only when all values are successful. The result is an array of returned values
  • If one fails, it fails directly, returning the result and status of the first failed Promise
const p1 = new Promise((resolve,reject) = > {
           setTimeout(() = > {
              resolve('success')},1000)})const p2 = Promise.resolve('the p2 - success')
const p3 = Promise.resolve('p3 - success')
Promise.race([p1,p2,p3])
Copy the code

7. Promise. Race method: (promises) => {}

(1) Promises: Promises: n promises array The result state of the first completed promise is the final result state.

Promise key issues (Issues that must be addressed before encapsulation)

1. How to change the state of Promise

  • Resolve (value): Resolved if it is pending
  • Reject (reason): If the current is pending, it becomes Rejected
  • Throw an exception: If it is pending, it becomes Rejected
    const p = new Promise((resolve, reject) = > {
          / / 1. Resolve function
          //resolve('ok') // pending => fulfilled(resolved)
          / / 2. Reject function
          //reject('error') // pending => rejected
          // 3. Throw an error
           throw 'Something's wrong'
    })
Copy the code

2. Will multiple success/failure callbacks specified by a promise be called?

This is called whenever a promise changes to the corresponding state

const p = new Promise((resolve, reject) = > {
      resolve('OK')
})
p.then((value) = > {
    console.log(value + 'First callback function')
})
p.then((value) = > {
   console.log(value + 'Second callback function')})Copy the code

3. Change the promsise status and specify the callback function which is first and which is last?

(1) It is possible to specify a callback first and then change the state, but it is also possible to change the state first and then specify the callback.

  • Call resolve()/reject() directly in the executor
  • Delay calling then() longer

(3) When will the data be available?

  • If the callback is specified first, the callback function will be called when the state changes, retrieving the data
  • If the state is changed first, the callback function is called when the callback is specified, and the data is returned
// The resolve/then callback is executed first
const p = new Promise((resolve, reject) = > {
  // 1. When a task is synchronized, the state is changed first and then is executed
  // resolve('ok')
  For asynchronous tasks, execute then first and then change the state
  setTimeout(() = >{
    resolve('ok')
  })
})
p.then((value) = > {
  console.log(value)
})
Copy the code

4. Promise.then () returns a new promise.

  • (1) Summary: determined by the result of the execution of the callback function specified by THEN
  • (2) Detailed expression:
  • If an exception is thrown, the new promise changes to Rejected, and Reason is the exception thrown
  • If an arbitrary value is returned that is not promsie, the new Promise becomes resolved and value is the returned value
  • If another new promise is returned, the result of that promise becomes the result of the new promise

5. How does promise string together multiple action tasks?

  • Promise’s then() returns a new promise. A chain call to then() can be opened
  • Multiple synchronous/asynchronous tasks are concatenated through chained calls to THEN

6. Abnormal promise penetration

  • When using promise’s then chain invocation, the failed callback can be specified at the end
  • Any previous operations other than exceptions are passed to the final failed callback
const p = new Promise((resolve, reject) = > {
    resolve('ok')
})
p.then((value) = >{
    throw 'Wrong'
}).then((value) = >{
    console.log(value)
}).catch((reason) = > {
    // Result output ->' error '
    console.log(reason)
})
Copy the code

7. Break the Promise chain

  • When using a promise’s then chain call, it breaks in the middle, and no subsequent callback function is called
  • Method: Return a PEDding state promise object in the callback function
const p = new Promise((resolve, reject) = > {
    resolve('ok')
})
p.then((value) = >{
    // Break the Promise chain
    return new Promise((resolve, reject) = > {})
}).then((value) = > {
    console.log(value + 'Will not be executed')})Copy the code

Promise custom encapsulation

Description: Encapsulated ideas -> understand all the ideas of the Promise, according to the original Promise-> realize their Promise

1. Initial structure setup (define promise function and then function on prototype)

class Promise {
  constructor (executer) {
    executer()
  }
  then(){}}Copy the code

2. Implement the resolve and Reject methods of the Promise internal executor function calls

class Promise {
  // Define the Promise property
  PromiseState = 'pending'
  PromiseResult = null
  constructor (executer) {
    // Note that the status can only be changed once.
    // Change the state of the object [PromiseState]
    // Change the value of the object [PromiseResult]
    let resolve = (value) = > {
      if (this.PromiseState ! = ='pending') return
      this.PromiseState = 'fulfilled'
      this.PromiseResult = value
    }

    let reject = (reason) = > {
      if (this.PromiseState ! = ='pending') return
      this.PromiseResult = reason
      this.PromiseState = 'rejected'
    }
    // Handle the throw exception
    try {
      executer(resolve, reject)
    }catch (e) {
      reject(e)
    }
  }
  then(){}}Copy the code
// New encapsulates the Promise
const p = new Promise((resolve, reject) = > {
   resolve('ok')
  // reject('error')
  // throw 'error'
})
console.log(p)
Copy the code
  • Look at the result here, and instead of looking at each layer, try reject and throw

  • Output native Promise results

3. Implement – call THEN synchronously

  • The return value is promsie
  • Call then() immediately when the state changes
  • Call onResolved() and onRejected() back to the function
  • The result and status of then are determined by the return values of the callback functions onResolved() and onRejected()
class Promise {
  // Define the Promise property
  PromiseState = 'pending'
  PromiseResult = null
  // The constructor is implemented above and omitted here. You can look at point 2 and see the full code at the end
  constructor (executer) {... }// Two callback onResolved onRejected
  then(onResolved, onRejected) {
    // then returns a new promise
    return new Promise((resolve, reject) = > {
      // The status is success
      if (this.PromiseState === 'fulfilled') {
        // The result and state of the incoming PromiseResult THEN is determined by its return value
          let res = onResolved(this.PromiseResult)
          // 1. Return Promise
          if (res instanceof Promise) {
            res.then(v= >{
              resolve(v)
            }, r= > {
              reject(r)
            })
          }else {
            // 2. The return value is non-PROMISE -> return success directly
            resolve(res)
          }
      }
      // State is failure, pass in PromiseResult
      if(this.PromiseState === 'rejected') {
        // The result and state of the incoming PromiseResult THEN is determined by its return value
        let res = onRejected(this.PromiseResult)
        // 1. Return Promise
        if (res instanceof Promise) {
          res.then(v= >{
            resolve(v)
          }, r= > {
            reject(r)
          })
        }else {
          // 2. The return value is non-PROMISE -> return success directly
          resolve(res)
        }
      }
    })
  }
}
Copy the code

4. Implement – Call then asynchronously

  • The return value is promsie
  • The state of the promise is pending, then is executed synchronously, and the callback function is stored (multiple, promise can have multiple callbacks).
  • After the asynchronous function completes, change the state in resolve/ Reject
  • Call the stored callback function
  • Try catch Catches an error
  • Extract the funType public code
class Promise {
  // Define the Promise property
  PromiseState = 'pending'
  PromiseResult = null
  // Store the callback function for then
  callbacks = []
  constructor (executer) {
    // Note that the status can only be changed once.
    // Change the state of the object [PromiseState]
    // Change the value of the object [PromiseResult]
    let resolve = (value) = > {
      if (this.PromiseState ! = ='pending') return
      this.PromiseState = 'fulfilled'
      this.PromiseResult = value
      // Call the callback function after the asynchronous state changes
      this.callbacks.forEach((item) = >{ item.onResolved() })
    }
    let reject = (reason) = > {
      if (this.PromiseState ! = ='pending') return
      this.PromiseResult = reason
      this.PromiseState = 'rejected'
      // Call the callback function after the asynchronous state changes
      this.callbacks.forEach((item) = >{ item.onRejected() })
    }
    // Handle the throw exception
    try { executer(resolve, reject) }
    catch (e) { reject(e) }
  }
  // Two callback onResolved onRejected
  then(onResolved, onRejected) {
    // then returns a new promise
    return new Promise((resolve, reject) = > {
      // Extract the common code
      let funType = (type) = >{
        try {
          let res = type(this.PromiseResult)
          if(res instanceof Promise) {
            res.then(v= > { resolve(v) }, r= > { reject(r) })
          } else {resolve(res) } // Return non-promise returns success directly
        }catch (e) {
          reject(e)
        }
      }
      // Pass the result and state of the PromiseResult then, as determined by the return value of funType
      // The status is success
      if (this.PromiseState === 'fulfilled') { funType(onResolved) }
      // State is failed,
      / / incoming PromiseResult
      if(this.PromiseState === 'rejected') { funType(onRejected) }
      // Store onResolved and onRejected -> to the callback attribute
      if(this.PromiseState === 'pending') {
        this.callbacks.push({
          onResolved: () = > { funType(onResolved) },
          onRejected: () = >{ funType(onRejected) }
        })
      }

    })
  }
}
Copy the code

5. Catch method

  • The catch method is the syntactic sugar for then
Class Promise {// Define Promise attribute PromiseState = 'pending' PromiseResult = null // Store then callback = [] constructor (executer) {... } // onResolved onRejected then(onResolved, onRejected) {... } // Add a catch method catch(onRejected) {return this. Then (onRejected)}}Copy the code

6. Exception penetration and value passing

  • Can allow the onResolved/onRejected argument not to be passed
  • Implementation: No parameters, internal definition of a function
if (typeofonResolved ! = ='function') {
// If the success function is not defined, pass the value directly
  onResolved = value= > value

}
if(typeofonRejected ! = ='function') {
 // An error is thrown when a failed function is not defined
  onRejected = (reason) = >{
    throw reason
  }
}
Copy the code

7. The then callback function executes asynchronously

  • The then method is executed asynchronously, after the synchronous code has finished executing
  • We wrapped the code on the left, and the native Promise on the right

  • Promises that implement their own packaging can be executed asynchronously
  • In this code, add setTimeout when calling onResovled and onRejected

8. All source code for encapsulated Promise constructors and then methods on the prototype chain

class Promise {
  // Define the Promise property
  PromiseState = 'pending'
  PromiseResult = null
  // Store the callback function for then
  callbacks = []
  constructor (executer) {
    // Note that the status can only be changed once.
    // Change the state of the object [PromiseState]
    // Change the value of the object [PromiseResult]
    let resolve = (value) = > {
      if (this.PromiseState ! = ='pending') return
      this.PromiseState = 'fulfilled'
      this.PromiseResult = value
      // Call the callback function after the asynchronous state changes
      this.callbacks.forEach((item) = >{
        setTimeout(() = > {
          item.onResolved()
        })
      })
    }
    let reject = (reason) = > {
      if (this.PromiseState ! = ='pending') return
      this.PromiseResult = reason
      this.PromiseState = 'rejected'
      // Call the callback function after the asynchronous state changes
      this.callbacks.forEach((item) = >{
        setTimeout(() = > {
          item.onRejected()
        })
      })
    }
    // Handle the throw exception
    try { 
      executer(resolve, reject) 
    }
    catch (e) { 
      reject(e) 
    }
  }
  // Two callback onResolved onRejected
  then(onResolved, onRejected) {
  // If the success function is not defined, pass the value directly
    if (typeofonResolved ! = ='function') {
      onResolved = value= > value
    }
    // An error is thrown when a failed function is not defined
    if(typeofonRejected ! = ='function') {
      onRejected = (reason) = >{
        throw reason
      }
    }
    // then returns a new promise
    return new Promise((resolve, reject) = > {
      // Extract the common code
      let funType = (type) = >{
        try {
          if (typeoftype ! = ='function') return
          let res = type(this.PromiseResult)
          if(res instanceof Promise) {
            res.then(v= > { 
              resolve(v) 
            }, r= > { 
              reject(r) 
            })
          } else {// Return non-promise returns success directly
            resolve(res) 
          } 
        }catch (e) {
          reject(e) 
        }
      }
      // Pass the result and state of the PromiseResult then, as determined by the return value of funType
      // 1. The status is success
      if (this.PromiseState === 'fulfilled') {
        setTimeout(() = > {
          funType(onResolved)
        })
      }
      // 2. The status is failed
      if(this.PromiseState === 'rejected') {
        setTimeout(() = > {
          funType(onRejected)
        })
      }
      // Store onResolved and onRejected -> to the callback attribute
      if(this.PromiseState === 'pending') {
        this.callbacks.push({
          onResolved: () = > { funType(onResolved)},
          onRejected: () = >{ funType(onRejected) }
        })
      }
    })
  }

  catch(onRejected) {
    return this.then(undefined, onRejected)
  }
}
Copy the code

9. Promise function object ->resolve method

  • Does not belong to the instance object
  • Declare static methods (part of the Promise function) using the static keyword
static resolve (value) {
  return new Promise((resolve, reject) = >{
    // Same as then method
    if (value instanceof Promise) {
      value.then(v= > {
        resolve(v)
      }, r= > {
        reject(r)
      })
    } else {
      resolve(value)
    }
  })
}
Copy the code

10. Promise function object -> Reject

static reject (reason) {
  // Always return failed promises
  return new Promise((resolve, reject) = > {
    reject(reason)
  })
}
Copy the code

11. Promise function object ->all method

static all (promises) {
  // Return a new promise
  // The status is returned as a successful array of returned values
  // If it fails, the result and status of the first failed Promise is returned
  // Store the returned results sequentially, whether synchronous or asynchronous
  return new Promise((resolve, reject) = > {
    let arr = []
    let num = 0
    for(let i= 0; i< promises.length; i++) {
      promises[i].then(v= > {
        num++
        arr[i] = v
        // Only if the last promise succeeds and makes it this far will all be successful
        if (num  ===  promises.length) {
          resolve(arr)
        }
      }, r= >{
        reject(r)
      })
    }
  })
}
Copy the code

12. Promise function object ->race method

static race (promises) {
  // Return a new promise. The result state of the first completed promise is the final result state
  return new Promise((resolve, reject) = > {
    for(let i= 0; i< promises.length; i++) {
      promises[i].then( v= > {
        resolve(v)
      }, r= >{
        reject(i)
      })
    }
  })
}
Copy the code

Anync and await

anync

  • Async functions have the same rules as Promise’s then methods
  • Return a Promise
  • Its result and state are determined by the return value of the function
async function test () {
    return 'ok'
}
test()
The test function returns a Promise
Copy the code

Await the expression

  • The expression on the right side of the await is generally called a Promise object and can also be a value directly
  • If the expression is a Promise, the value of a successful Promise is returned
  • If the expression is any other value, return that value directly
  • Await must be written in async functions, but async functions can have no await
  • If an await promise fails, an exception is thrown, requiring a try… Catch processing

Anync is used in combination with await

  • Promise is actually a programming trick to avoid callback hell by changing the callback function to a chained call. The biggest problem is the code redundancy. The original task is packaged by Promise. No matter what the operation is, it is a pile of THEN at a glance, and the original semantics become unclear.
  • Here async and await are used to make the semantics seem clear.
// It needs to be used in node and environment
// Practice reading the contents of one and two folders
const fs = require('fs')
const util = require('util')
const mineReadFile = util.promisify(fs.readFile) // Return a Promise
async function readFile() {
    try{
        const d1 = await mineReadFile('./resource/one.txt')
        const d2 = await  mineReadFile('./resource/two.tx')
        console.log(d1 + d2)
    }catch (e) {
        console.log(e)
    }
}
readFile()
Copy the code

Code that encapsulates the Promise

class Promise {
  // Define the Promise property
  PromiseState = 'pending'
  PromiseResult = null
  // Store the callback function for then
  callbacks = []
  constructor (executer) {
    // Note that the status can only be changed once.
    // Change the state of the object [PromiseState]
    // Change the value of the object [PromiseResult]
    let resolve = (value) = > {
      if (this.PromiseState ! = ='pending') return
      this.PromiseState = 'fulfilled'
      this.PromiseResult = value
      // Call the callback function after the asynchronous state changes
      this.callbacks.forEach((item) = >{
        setTimeout(() = > {
          item.onResolved()
        })
      })
    }
    let reject = (reason) = > {
      if (this.PromiseState ! = ='pending') return
      this.PromiseResult = reason
      this.PromiseState = 'rejected'
      // Call the callback function after the asynchronous state changes
      this.callbacks.forEach((item) = >{
        setTimeout(() = > {
          item.onRejected()
        })
      })
    }
    // Handle the throw exception
    try {
      executer(resolve, reject)
    }
    catch (e) {
      reject(e)
    }
  }
  // Two callback onResolved onRejected
  then(onResolved, onRejected) {
  // If the success function is not defined, pass the value directly
    if (typeofonResolved ! = ='function') {
      onResolved = value= > value
    }
    // An error is thrown when a failed function is not defined
    if(typeofonRejected ! = ='function') {
      onRejected = (reason) = >{
        throw reason
      }
    }
    // then returns a new promise
    return new Promise((resolve, reject) = > {
      // Extract the common code
      let funType = (type) = >{
        try {
          if (typeoftype ! = ='function') return
          let res = type(this.PromiseResult)
          if(res instanceof Promise) {
            res.then(v= > {
              resolve(v)
            }, r= > {
              reject(r)
            })
          } else {// Return non-promise returns success directly
            resolve(res)
          }
        }catch (e) {
          reject(e)
        }
      }
      // Pass the result and state of the PromiseResult then, as determined by the return value of funType
      // 1. The status is success
      if (this.PromiseState === 'fulfilled') {
        setTimeout(() = > {
          funType(onResolved)
        })
      }
      // 2. The status is failed
      if(this.PromiseState === 'rejected') {
        setTimeout(() = > {
          funType(onRejected)
        })
      }
      // Store onResolved and onRejected -> to the callback attribute
      if(this.PromiseState === 'pending') {
        this.callbacks.push({
          onResolved: () = > { funType(onResolved)},
          onRejected: () = >{ funType(onRejected) }
        })
      }
    })
  }

  catch(onRejected) {
    return this.then(undefined, onRejected)
  }

  static resolve (value) {
    return new Promise((resolve, reject) = >{
      // Same as then method
      if (value instanceof Promise) {
        value.then(v= > {
          resolve(v)
        }, r= > {
          reject(r)
        })
      } else {
        resolve(value)
      }
    })
  }

  static reject (reason) {
    // Always return failure
    return new Promise((resolve, reject) = > {
      reject(reason)
    })
  }

  static all (promises) {
    // Return a new promise
    // The status is returned as a successful array of returned values
    // If it fails, the result and status of the first failed Promise is returned
    // Store the returned results sequentially, whether synchronous or asynchronous
    return new Promise((resolve, reject) = > {
      let arr = []
      let num = 0
      for(let i= 0; i< promises.length; i++) {
        promises[i].then(v= > {
          num++
          arr[i] = v
          // Only if the last promise succeeds and makes it this far will all be successful
          if (num  ===  promises.length) {
            resolve(arr)
          }
        }, r= >{
          reject(r)
        })
      }
    })
  }

  static race (promises) {
    // Return a new promise. The result state of the first completed promise is the final result state
    // Store the returned results sequentially, whether synchronous or asynchronous
    return new Promise((resolve, reject) = > {
      for(let i= 0; i< promises.length; i++) {
        promises[i].then( v= > {
          resolve(v)
        }, r= >{
          reject(r)
        })
      }
    })
  }
}
Copy the code