Promise之实现自己的promise②

164 阅读2分钟

这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战

我们在前面的文章介绍了Promise的相关知识,及它的一些方法。下面我们就来实现一个自己的Promise,我们知道Promise()是一个构造函数,可以创建一个新的Promise对象。所以在这里我使用ES6的方式来定义一个类MyPromise.

executor

executor对应的就是MyPromise类中的构造函数,在构造函数中,需要立即执行excutor()

 // 类
class MyPromise {
    // constructor:构造函数 executor:执行器
    constructor (executor) {
        executor(resolve, reject)
    }
}
module.exports = MyPromise;

为MyPromise定义状态

const PENDING = 'PENDING', FULFILLED = 'FULFILLED', REJECTED = 'REJECTED';

Promise中初始化的状态为pending状态,只能由pending转为其他状态(resolve或者reject),而且不能在转回去。

image.png

// 每个promise,都有自己的执行器 —— 有自己的resolve,reject。ES6中,如果在外面定义方法,实际上是定义在prototype上面了
    /**
     * @description 定义函数resolve:更改状态
     */    
    const resolve = (value) => {
      if (this.status === PENDING) {
        this.status = FULFILLED;
        this.value = value;
      }  
    }
    /**
     * @description 定义函数reject:更改状态
     */    
    const reject = (reason) => {
      if (this.status === PENDING) {
        this.status = REJECTED;
        this.reason = reason;
      }
    }

实现then方法

then方法中有成功的回调(onFulfilled)和失败的回调(onRejected)两个参数。

promise.then(onFulfilled, onRejected)

then(onFulfilled, onRejected) {
    // onFulfilled执行条件
    if (this.status === FULFILLED) {
      onFulfilled(this.value);
    }
    // onRejected执行条件
    if (this.status === REJECTED) {
      onRejected(this.reason);
    }
  }

image.png

注意:捕获异常,如果有异常,直接执行rejected

// 捕获异常,如果有异常,直接执行rejected
try {
  executor(resolve, reject);
} catch (error) {
  reject(error);
}

image.png

最基本版的promise实现

代码如下:

MyPromise类: image.png

调用自己的Promise: image.png

简单版promise基本实现,但还有很多问题,比如:

  • 遇到异步问题如何解决?
  • promise.then的链式调用如何实现?

这里接着做一些扩展。之前简单版promise还存在着一些问题,比如在promise中出现了异步的程序如何解决?

处理Promise中的异步与多次调用的问题

异步程序是说excutor执行器在执行之后的状态并没有改变,所以在then的时候并不知道走那个状态。 需要在then中处理pending这个状态的。并且then方法要按照调用的原有顺序去执行,依次去执行成功的回调或者是失败的回调。

  • 在pending状态的时候去收集成功的回调或者是失败的回调
  • 在构造函数中定义onFulfilledCallbacks收集成功的回调,定义onRejectedCallbacks收集失败的回调——这里要用到发布订阅模式

image.png

image.png