手写Promise

81 阅读2分钟

复习时看到手写Promise是经常考到的,因此记录下来自己的理解。 遇到手写Promise,首先要回忆一下Promise的基本用法

Promise基本用法

  • promise是一个类,需要使用new关键词调用它,new一个promise的时候需要传递一个executor执行函数;
  • 该执行函数有两个参数:resolve与reject,两个参数都是函数;
  • 执行resolve函数将promise状态由pending变为onfulfilled且不可再次改变;
  • 执行reject函数将promise状态由pending变为rejected,同样不可再次改变; 如:
let p1 = new Promise((resolve, reject) => {
  resolve("成功");
});
console.log(p1);

结果: image.png

初步实现1

const PENDING = "pending";
const RESOLVED = "onfulfilled";
const REJECTED = "rejected";
class MyPromise {
  constructor(executor) {
    console.log("executor函数:", executor);//外部传入的executor函数,该函数需要两个参数由promise内部提供
    this.state = PENDING;
    this.value = undefined;
    this.error = undefined;

    const resolve = (val) => {
      if (this.state === PENDING) {
        this.state = RESOLVED;
        this.value = val;
      }
    };
    const reject = (err) => {
      if (this.state === PENDING) {
        this.state = REJECTED;
        this.error = err;
      }
    };
    executor(resolve, reject); //传入resolve与reject函数
  }
  //executor函数
}
//resolve与reject相当于两个参数

then属性

构造出的promise实例可以调用then方法;then方法接收两个参数,一个是成功时的回调函数onFulfilled,一个是失败时的回调函数onRejected。当我们调用实例上的then方法时,如果promise实例是成功的状态,则会调用onFulfilled,参数为promise实例的成功值;如果promise实例是失败的状态,则会调用onRejected,参数为promise实例失败的错误原因error onFulfilled与onRejected都是外部提供的

  then(onFulfilled, onRejected) {
    if (this.state === RESOLVED) {
      onFulfilled(this.value);
    }
    if (this.state === REJECTED) {
      onRejected(this.error);
    }
  }

then属性的异步执行

当promise构造时的executor函数里出现了异步任务,如:

let p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("成功");
  }, 1000);
});
p2.then(
  (res) => {},
  (err) => {}
);

在执行then时p2的状态还不确定,因此无法执行,所以要改善异步处理的代码,解决思路时:加入待处理的成功任务队列以及失败任务队列,当对应的状态变化时再去执行任务队列里的任务 代码实现 then中的:

  then(onFulfilled, onRejected) {
    if (this.state === RESOLVED) {
      onFulfilled(this.value);
    }
    if (this.state === REJECTED) {
      onRejected(this.error);
    }
    if (this.state === PENDING) {
      this.onFulfilledCallbacks.push(() => {
        //这里记得要传参,注意箭头函数以及执行函数的区别
        onFulfilled(this.value);
      });
      this.onRejectedCallbacks.push(() => {
        onRejected(this.error);
      });
    }
  }

状态变化函数:

const resolve = (val) => {
  if (this.state === PENDING) {
    this.state = RESOLVED;
    this.value = val;
    //执行成功任务队列
    this.onFulfilledCallbacks.forEach((fn) => {
      fn();
    });
  }
};
const reject = (err) => {
  if (this.state === PENDING) {
    this.state = REJECTED;
    this.error = err;
    //执行暂存的失败任务队列
    this.onRejectedCallbacks.forEach((fn) => {
      fn();
    });
  }
};

至此一个基本版的promise便可以实现,但是后续还有then的链式调用等问题需要深入,将补习一些知识后继续书写