从浅入深的Promise(下)

153 阅读3分钟

前言

  1. 想手写实现一个Promise先要知道Promise的原理和他内部的流程
  2. 我们知道的Promise就是一个异步对象,可以传入一个带有resolve, reject参数的函数。
  3. Promise里还有自己的状态,Pending 为初始的状态,Fulfilled 为成功的状态,Rejected 为失败的状态。
  4. 这里的状态是不可逆的,就是一个Promise对象状态一旦发生改变就不会再转换回去,这里其实就为我们后续调用的函数提供了保证。(PS: Promise对象里的代码是同步执行的)
    不同状态有与之对应的实例方法来执行后续的逻辑
    promise.then():获取异步任务的正常结果,
    promise.catch():获取异步任务的异常结果,
    promise.finaly():异步任务无论成功与否,都会执行。
  5. Promise还有一个很重要的链式调用,就是Promise的返回都是一个Promise对象,可以继续执行后续的状态方法的调用。如果逻辑需要中断可以在需要中断的地方手动的抛出一个throw错误来中断链式调用。
  6. 还有两个使用的方法
    promise.all (): 并发处理多个异步任务,所有任务都执行成功,才能得到结果
    promise.race (): 并发处理多个异步任务,只要有一个任务执行成功,就能得到结果

补充一些Class类的知识:

  1. class中可以看到里面有一个constructor()方法,这就是构造方法,而this关键字则代表实例对象。
  2. class类除了构造方法constructor,还能定义其他方法。注意,如定义toString()方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法与方法之间不需要逗号分隔,加了会报错。
  3. 获取原型链上的方法Object.getOwnPropertyNames(Point.prototype)
  4. constructor()方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor()方法,如果没有显式定义,一个空的constructor()方法会被默认添加。
  5. constructor()方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
  6. 类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别

步入正题,手撕Promise

 class Promise1 {
      // executor里面有两个参数,一个叫resolve(成功),一个叫reject(失败)
      constructor(executor) {
        // 初始化status有三个值 pending fulfiled rejected
        this.status = 'pending'
        this.success = null // success  error返回的数据,可合并成一个变量
        this.error = null
        this.resolvedCallback = [] // 将then方法里的两个函数存储起来,一个promise可以有多个then,因此存放在一个数组内
        this.rejectCallback = []


        // 执行resolve或reject函数,status状态改变为(fulfilled rejected)
        let resolve = (value) => {
          if (this.status === 'pending') {
            this.status = 'fulfilled'
            this.success = value
            this.resolvedCallback.forEach(fn => fn())
          }
        }
        let reject = (value) => {
          if (this.status === 'pending') {
            this.status = 'reject'
            this.error = value
            this.rejectCallback.forEach(fn => fn())
          }
        }
        try {
          executor(resolve, reject)
        } catch (e) {
          reject(e)
        }
      }

      then (onFulfilled, onRejected) {
        // 如果传入的两个参数不是函数,则直接执行返回结果
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : () => { }
        onRejected = typeof onRejected === 'function' ? onRejected : () => { }

        // 为了达成链式,我们默认在第一个then里返回一个promise。
        let promise2 = new Promise1((resolve, reject) => {
          if (this.status === 'fulfilled') {
            let data = onFulfilled(this.success)
          }
          if (this.status === 'rejected') {
            onRejected(this.error)
          }
          // then时status还是pending状态 需要在then调用的时候,将成功和失败存到各自的数组,一旦reject或者resolve,就调用它们
          if (this.status === 'pending') {
            this.resolvedCallback.push(() => { onFulfilled(this.success) })
            this.rejectCallback.push(() => { onRejected(this.error) })
          }
        })
        return promise2
      }
      catch () {
        onRejected(this.error)
      }
    }
    const p = new Promise1((resolve, reject) => {
      // resolve('成功返回')
      reject('返回失败s')
    })
    p.then((value) => {
      console.log(value)
    })
    p.catch(value => {
      console.log(value)
    })
    console.log(p)