One, foreword

Q: What is it? What to do? How to do?

  1. What is? —-Promise is a solution to asynchronous programming, a new object added to ES6 to deliver messages for asynchronous operations. It represents some event (usually an asynchronous operation) whose outcome is known in the future, and it provides a uniform API for further processing.

  2. What to do? —-Promise solves the problem of callback hell. In multiple nested callback methods, if there are synchronous and asynchronous methods at the same time, the actual execution order will be chaotic, which is not easy to debug and maintain.

  3. How to do? 3.1 Suppose there is a requirement that when connecting to the server interface, it wants to get the data5 returned by the interface URL of ‘URL5’, but URL5 needs the data returned by URL4 as the parameter, urL4 needs the data returned by URL3 as the parameter, and so on. (The nesting level is slightly exaggerated. However, in actual development, it is often the case that the data returned by the previous interface is passed as the parameters of the next interface.

        $.get('/url1'.function (data1) {
          $.get('/url2', data1, function (data2) {
            $.get('/url3', data2, function (data3) {
              $.get('/url4', data3, function (data4) {
                $.get('/url5', data4, function (data5) {
                    console.log(data5) 
                  })
              })
            })
          })
        })
    Copy the code

    Use the Promise solution:

    let promise = new Promise((resolve, reject) = > {
      $.get('/url1'.data1= > {
        resolve(data1)
      })
    })
    
    promise.then((data1) = > {
      $.get('/url2', data1, data2= > {
        return data2
      })
    }).then((data2) = > {
      $.get('/url3', data2, data3= > {
        return data3
      })
    }).then((data3) = > {
      $.get('/url4', data3, data4= > {
        console.log(data4)
      })
    })
    
    Copy the code

Second, Promise use principle analysis

  1. PromiseIt’s a class, and when you execute that class, you have to pass in an executor, and the executor executes immediately

  2. PromiseThere are three states, which are waitingpendingThat successfulfilled, failurerejected

    pending -> fulfilled

    pending -> rejected

    Once the status is determined, it cannot be changed

  3. resolveandrejectFunctions are used to change state

    resolve:fulfilled

    reject:rejected

  4. thenWhat the method does internally is it determines the state and if the state is success it calls the successful callback and if the state is failure it calls the failed callback

    thenMethods are defined in the prototype object
  5. thenThe success callback takes one parameter to indicate the value after successthenFailure to call back a parameter, indicating the cause of the failure

Third, write Pormise

  1. createMypromise.jsAccording to the principle analysis of 1.2.3 above, we define three states and create oneMyPromiseOf the class, the actuator executes immediately, and the initialization state isPENDINGTo defineresolve.rejectMethod with the following code:
    const PENDING = "pending" / / wait for
    const FULFILLED = "fulfilled" / / success
    const REJECT = "reject" / / fail
    
    class MyPromise {
      constructor(executor) {
        executor(this.resolve, this.reject)
      }
      // The initial state waits
      status = PENDING

      resolve = () = > {
        // If the state is not waiting prevents the program from executing downward
        if (this.status ! == PENDING)return
        // Change the status to Successful
        this.status = FULFILLED
      }
      reject = () = > {
        // If the state is not waiting prevents the program from executing downward
        if (this.status ! == PENDING)return
        // Change the state to failed
        this.status = REJECT
      }
    }
Copy the code
  1. According to the appeal 4. 5. Principle analysis, we need to definethenMethod, mainly to determine the current state of the call success or failure of the function, need to be declared in advancesuccessCallbackandfailCallbackAre the success and failure callback functions, respectively. The value of success needs to be passed in the callback functionvalueOr send an error messagereason, sovalueandreasonTo be declared in advance, the code is as follows:
    // Declare the initial value returned on success
    value = undefined
    // Declare the reason for the return failure
    reason = undefined
    // Declare the successful callback function
    successCallback = undefined
    // Declare the failure callback function
    failCallback = undefined
    then (successCallback, failCallback) {
        if (this.status === FULFILLED) {
          successCallback(this.value)
        } else if (this.status === REJECT) {
          failCallback(this.reason)
        }
    }
Copy the code

Because we need to pass value and Reason values to the successCallback and failCallback callbacks in our then method, we should save the value and reason values in resolve and Reject, respectively. Change the code as follows:

    resolve = value= > {
        // If the state is not waiting prevents the program from executing downward
        if (this.status ! == PENDING)return
        // Change the status to Successful
        this.status = FULFILLED
        // Save the successful value and pass it to the then method
        this.value = value
        }
        reject = reason= > {
        // If the state is not waiting prevents the program from executing downward
        if (this.status ! == PENDING)return
        // Change the state to failed
        this.status = REJECT
        // Save the cause after the failure, and pass it to the then method
        this.reason = reason
    }
Copy the code

At this point, the base is complete and needs module.exports = MyPromise export

Iv. Final code and usage

MyPromise.js

    const PENDING = "pending" / / wait for
    const FULFILLED = "fulfilled" / / success
    const REJECT = "reject" / / fail

    class MyPromise {
      constructor(executor) {
        executor(this.resolve, this.reject)
      }
      // The initial state waits
      status = PENDING
      // Declare the initial value returned on success
      value = undefined
      // Declare the reason for the return failure
      reason = undefined
      // Declare the successful callback function
      successCallback = undefined
      // Declare the failure callback function
      failCallback = undefined
      resolve = value= > {
        // If the state is not waiting prevents the program from executing downward
        if (this.status ! == PENDING)return
        // Change the status to Successful
        this.status = FULFILLED
        // Save the successful value and pass it to the then method
        this.value = value
      }
      reject = reason= > {
        // If the state is not waiting prevents the program from executing downward
        if (this.status ! == PENDING)return
        // Change the state to failed
        this.status = REJECT
        // Save the cause after the failure, and pass it to the then method
        this.reason = reason
      }
      then (successCallback, failCallback) {
        if (this.status === FULFILLED) {
          successCallback(this.value)
        } else if (this.status === REJECT) {
          failCallback(this.reason)
        }
      }
    }

    module.exports = MyPromise
Copy the code

Create index.js to import our Pormise class and use it with the following code:

const MyPromise = require('./MyPromise') let promise = new MyPromise((resolve, Reject) => {resolve(' reject ') // reject(' failure message ')}) promise.then(value => {console.log(value) // success}, Reason => {console.log(reason) // failure information})Copy the code

Enter node index.js in the console to start