一起手写吧!Promise!

1、Promise 的声明

首先呢,promise肯定是一个类,我们就用class来声明。

  • 由于new Promise((resolve, reject)=>{}),所以传入一个参数(函数),秘籍里叫他executor,传入就执行。
  • executor里面有两个参数,一个叫resolve(成功),一个叫reject(失败)。
  • 由于resolve和reject可执行,所以都是函数,我们用let声明。
class Promise{
  // 构造器
  constructor(executor){
    // 成功
    let resolve = () => { };
    // 失败
    let reject = () => { };
    // 立即执行
    executor(resolve, reject);
  }
}

解决基本状态

秘籍对Promise有规定:

  • Promise存在三个状态(state)pending、fulfilled、rejected

  • pending(等待态)为初始态,并可以转化为fulfilled(成功态)和rejected(失败态)

  • 成功时,不可转为其他状态,且必须有一个不可改变的值(value)

  • 失败时,不可转为其他状态,且必须有一个不可改变的原因(reason)

  • new Promise((resolve, reject)=>{resolve(value)}) resolve为成功,接收参数value,状态改变为fulfilled,不可再次改变。

  • new Promise((resolve, reject)=>{reject(reason)}) reject为失败,接收参数reason,状态改变为rejected,不可再次改变。

  • 若是executor函数报错 直接执行reject();

于是乎,我们获得以下代码

class Promise{
  constructor(executor){
    // 初始化state为等待态
    this.state = 'pending';
    // 成功的值
    this.value = undefined;
    // 失败的原因
    this.reason = undefined;
    let resolve = value => {
      // state改变,resolve调用就会失败
      if (this.state === 'pending') {
        // resolve调用后,state转化为成功态
        this.state = 'fulfilled';
        // 储存成功的值
        this.value = value;
      }
    };
    let reject = reason => {
      // state改变,reject调用就会失败
      if (this.state === 'pending') {
        // reject调用后,state转化为失败态
        this.state = 'rejected';
        // 储存失败的原因
        this.reason = reason;
      }
    };
    // 如果executor执行报错,直接执行reject
    try{
      executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }
}

then方法

秘籍规定:Promise有一个叫做then的方法,里面有两个参数:onFulfilled,onRejected,成功有成功的值,失败有失败的原因

  • 当状态state为fulfilled,则执行onFulfilled,传入this.value。当状态state为rejected,则执行onRejected,传入this.reason
  • onFulfilled,onRejected如果他们是函数,则必须分别在fulfilled,rejected后被调用,value或reason依次作为他们的第一个参数
class Promise{
  constructor(executor){...}
  // then 方法 有两个参数onFulfilled onRejected
  then(onFulfilled,onRejected) {
    // 状态为fulfilled,执行onFulfilled,传入成功的值
    if (this.state === 'fulfilled') {
      onFulfilled(this.value);
    };
    // 状态为rejected,执行onRejected,传入失败的原因
    if (this.state === 'rejected') {
      onRejected(this.reason);
    };
  }
}

这下武学初成,可以对付对付江湖小杂毛了,但是对于带setTimeout的江洋大盗还是没辙。

原文地址:https://www.cnblogs.com/magicg/p/12791045.html