【无标题】JavaScript手写系列(三)——Promise

前言

Promise也是面试中常考的问题,在日常工作中倒是常常用到,但真要让我说一下,我还真的说不出来,所以我这里直接截图阮一峰《# ECMAScript 6 入门》的定义:

在这里插入图片描述

Promise对三种状态:Pending、fullfiled、reject,两个特点状态变化不受外界影响一旦状态改变,就不会再变,任何时候都可以得到这个结果,接下来我就带大姐来实现一个简单的Promise
1.首先我们来定义三个静态变量保存Promise的三种状态。

class MyPromise {
  // 定义promise3种状态 pending fulfilled rejected
  static Pending = "pending";
  static Fulfilled = "fulfilled";
  static Rejected = "rejected";
}

2.下来再定义constructor构造函数,该函数接受一个回调函数

 constructor(callback) {
    this.promiseStatus = MyPromise.Pending; // 状态
    this.promiseResult = null; // 执行结果
    this.fulfilledCallbacks = [];  // 成功调用栈
    this.rejectedCallbacks = [];  // 失败调用栈
    try {
      callback(this.resolve.bind(this), this.reject.bind(this)); // 执行传入的函数
    } catch (err) {
      console.log(111, err);
      this.reject(err);
    }
  }

3.实现成功回调函数resolve.

// 实现resolve
  resolve(result) {
    setTimeout(() => {
      if (this.promiseStatus == "pending") {
        this.promiseStatus = "fulfilled";
        this.promiseResult = result;
        this.fulfilledCallbacks.forEach((callback) => { // 循环调用成功回调函数
          callback(result);
        });
      }
    });
  }

我们用setTimeout来模拟异步,当状态为pending时,将成功结果赋值给Promise执行结果,并循环执行成功回调函数,执行完毕后,Promise状态由pending变为fullfilled
4.实现失败回调函数reject
该函数接收Promise回调函数执行失败的的原因作为参数。

 // 实现reject
  reject(reason) {
    setTimeout(() => {
      if (this.promiseStatus == "pending") {
        this.promiseStatus = "rejected"; // 执行后将状态变更为rejected
        this.promiseResult = reason;  // 返回失败原因
        this.rejectedCallbacks.forEach((callback) => { // 循环执行失败回调
          callback(reason);
        });
      }
    });
  }

5.实现then链式调用
该函数接收成功回调和失败回调作为参数

  then(onFulfilled, onRejected) {
    onFulfilled =
      typeof onFulfilled == "function"
        ? onFulfilled
        : (value) => {
            return value;
          }; // 如果有传入的成功回调函数,直接使用,没有就把传入值作为返回值
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (reason) => {
            return reason;
          }; // // 如果有传入的失败回调函数,直接使用,没有就把传入值作为返回值
    if (this.promiseStatus == "pending") { // 如果是pending状态 则将两个回调分别加入回调栈中
      this.fulfilledCallbacks.push(onFulfilled);
      this.rejectedCallbacks.push(onRejected);
    }
    if (this.promiseStatus == "fulfilled") { // 成功则加入成功回调栈
      setTimeout(() => {
        onFulfilled(this.promiseResult);
      });
    }
    if (this.promiseStatus == "rejected") { // 失败加入失败回调
      setTimeout(() => {
        onRejected(this.promiseResult);
      });
    }
  }

6.代码验证

const promise = new MyPromise((resolve, reject) => {
  setTimeout(() => {
      resolve('success')
  }, 2000);
})
promise.then(value => {
  console.log(1)
  console.log('resolve', value)
})
promise.then(value => {
  console.log(2)
  console.log('resolve', value)
})
promise.then(value => {
  console.log(3)
  console.log('resolve', value)
})

打印执行顺序

在这里插入图片描述

如果将resolve('success')改为reject('fail'),则只答应三个fail,catche还未实现。
以上就是简易版Promise的实现,喜欢就点个赞吧。

猜你喜欢

转载自blog.csdn.net/Salange1/article/details/127581251
今日推荐