手写Promise(乞丐版呜呜呜)

330 阅读2分钟

首先我们需要先规定一下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 MyPromise{
    constructor(executor){
    //首先先定义状态,resolve的参数,reject的参数
        this.state='pending';
        this.value=undefined;
        this.reason=undefined;
        
        let resolve=(value)=>{
        //在此判断是否为pending状态,是为了确保pending状态一旦转化为fulfilled就不能在改变了
            if(this.state=='pending'){
                this.state='fulfilled';
                this.value=value;
            }
        }
        
        let reject=(reason)=>{
              if(this.state=='pending'){
                this.state='rejected';
                this.reason=reason;
            }
        }
        
        try{
            executor(resolve,reject)
        }catch(err){
            reject(err)
        }
    }
    
}

then方法

• Promise中的then方法有两个参数:onFulfilled,onRejected,成功有成功的值,失败有失败的原因

• 当状态state为fulfilled,则执行onFulfilled,传入this.value。当状态state为rejected,则执行onRejected,传入this.value

class MyPromise{
    constructor(executor){...}
    then(onFulfilled,onRejected){
        if(this.state=='fulfilled'){
            onFulfilled(this.value)
        }
        if(this.state=='rejected'){
            onRejected(this.reason)
        }
    }
    }

解决异步实现

let p1=new MyPromise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('成功了')
    },100)
})
p1.then((value)=>{
    console.log(value) 
},(err)=>{
    console.log(err)
})

• 当resolve在setTimeout中时,then中的state一直是pending状态,因此在then中根本就没有执行resolve,所以我们就需要在then调用的时候,state为pending的时候,将成功和失败存到各自的数组,一旦reject或者resolve,就调用它们(发布订阅模式)

• 由于一个promise可以有多个then,所以存在同一个数组内。

class MyPromise{
  constructor(executor){
    this.state = 'pending';
    this.value = undefined;
    this.reason = undefined;
    // 成功存放的数组
    this.onResolvedCallbacks = [];
    // 失败存放法数组
    this.onRejectedCallbacks = [];
    let resolve = value => {
      if (this.state === 'pending') {
        this.state = 'fulfilled';
        this.value = value;
        // 一旦resolve执行,调用成功数组的函数
        this.onResolvedCallbacks.forEach(fn=>fn());
      }
    };
    let reject = reason => {
      if (this.state === 'pending') {
        this.state = 'rejected';
        this.reason = reason;
        // 一旦reject执行,调用失败数组的函数
        this.onRejectedCallbacks.forEach(fn=>fn());
      }
    };
    try{
      executor(resolve, reject);
    } catch (err) {
      reject(err);
    }
  }
  then(onFulfilled,onRejected) {
    if (this.state === 'fulfilled') {
      onFulfilled(this.value);
    };
    if (this.state === 'rejected') {
      onRejected(this.reason);
    };
    // 当状态state为pending时
    if (this.state === 'pending') {
      // onFulfilled传入到成功数组
      this.onResolvedCallbacks.push(()=>{
        onFulfilled(this.value);
      })
      // onRejected传入到失败数组
      this.onRejectedCallbacks.push(()=>{
        onRejected(this.value);
      })
    }
  }
    
}

let p1=new MyPromise((resolve,reject)=>{
    setTimeout(()=>{
        resolve('成功了')
    },100)
})
p1.then((value)=>{
    console.log(value) //'成功了'
},(err)=>{
    console.log(err)
})