“This is the third day of my participation in the November Gwen Challenge. See details of the event: The last Gwen Challenge 2021”.

The first two articles are recommended

Tear Promise from scratch, master the realization principle of Promise. (1)

Tear Promise from scratch, master the realization principle of Promise. (2)

review

As described in the previous article, we have completed the basic version of promise, as follows

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'

class Promise{
  constructor(executor){

    this.state = PENDING
    this.value = undefined
    this.reason = undefined
    / / store onFulfilled
    this.onResolvedCallbacks = []
    / / store onRejected
    this.onRejectedCallbacks = []
    const resolve = (value) = > {
      if (this.state === PENDING) {
        this.value = value
        this.state = FULFILLED
        // The promise instance will call ondepressing after its state changes
        this.onResolvedCallbacks.forEach(fn= > fn())
      }
    }

    const reject = (reason) = > {
      if (this.state === PENDING) {
        this.reason = reason
        this.state = REJECTED
        // onRejected called after the promise instance state changes
        this.onRejectedCallbacks.forEach(fn= > fn())
      }
    }
    try {
      // An error in the execution of the executor function will cause the Promise to fail
      executor(resolve,reject)
    } catch (error) {
      reject(error)
    }
  }
  then(onFulfilled, onRejected){
    if (this.state === FULFILLED) {
      onFulfilled(this.value)
    }

    if (this.state === REJECTED) {
      onRejected(this.reason)
    }

    if (this.state === PENDING) {
      // If the state of the Promise instance is not determined at this time, we need to save onFulfilled and onRejected, and then invoke the promise instance after the state changes
      this.onResolvedCallbacks.push(() = > {
        onFulfilled(this.value)
      })
      this.onRejectedCallbacks.push(() = > {
        onRejected(this.reason)
      })
    }

  }
}
Copy the code

The callback hell

Before we implement Promise’s then chain invocation mechanism, let’s take a look at callback hell and how promises can be used to solve it.

  • There are two text filesage.txtandname.txt, contents are as follows.

  • I need to read itage.txtThen use this path to readname.txtThe content of the code below.
    const fs = require('fs') // Import the file module in node
    fs.readFile('./age.txt'.'utf8'.function(err, data){
      if(err) throw new Error(err)
      fs.readFile(data,'utf8'.function (err,data) {
          if(err) throw new Error(err)
          console.log(data)
      })
    })
    Copy the code
  • If we had multiple files nested like this, our code would look like this, which is what we call callback hell.
    fs.readFile('./age.txt'.'utf8'.function(err, data){
      if(err) throw new Error(err)
      fs.readFile(data,'utf8'.function (err,data) {
          if(err) throw new Error(err)
          fs.readFile(data,'utf8'.function (err,data) {
              if(err) throw new Error(err)
              fs.readFile(data,'utf8'.function (err,data) {
                  if(err) throw new Error(err)
                  fs.readFile(data,'utf8'.function (err,data) {
                    if(err) throw new Error(err)
                    console.log(data)
                })
              })
          })
      })
    })
    Copy the code
  • thenPromiseHow it solves callback hell as an asynchronous programming solution, let’s look at the code.
    • First we are going toreadFileMethod encapsulated intopromise
    const readFile = (filePath) = > {
        return new Promise((resolve,reject) = >{
             fs.readFile(filePath,'utf8'.function (err,data) {
                 if(err) {// Failed to call reject
                     return reject(err);
                 } 
                 resolve(data); // Resolve was successfully called})})}Copy the code
    • Use the one we encapsulatedreadFileGo to readage.txt.name.txt“, writing code is very friendly.
    readFile('./age.txt').then(data= > {
      return readFile(data)
    }).then(data= > {
      console.log(data)
    },reason= > {
      console.log(reason)
    })
    Copy the code
    • We got what we wanted

This article is mainly used to introduce callback hell, which will continue in the next articlePromise.