ytxbnahn / blog

my blog
1 stars 0 forks source link

实现一个简易的Promise #8

Open ytxbnahn opened 7 years ago

ytxbnahn commented 7 years ago

开始

构造函数

在我们使用 promise 时

var promise = new Promise((res, rej) => {
  something();
  res();
  something();
});
primise.then(() => {});
primise.then(() => {});

以上我们可以知道的 promise 需要接受一 function 参数,并将 res 和 rej 作为参数返回。允许 promise 添加多个 then,以下是我的定义

const PENDING = "PENDING";
const FULFILLED = "FULFILLED";
const REJECTED = "REJECTED";

class MyPromise {
  constructor(handle) {
    this._value = undefined; // 用于储存primise值
    this._status = PENDING; // Promise的初始状态为pending,它可以由此状态转换为fulfilled或者rejected,一旦状态确定,就不可以再次转换为其它状态。
    this._fulfilledQueue = []; // 用于储存多个then的方法
    this._rejectedQueue = [];
    handle(this._resolve, this._reject);
  }
  _resolve() {}
  _reject() {}
}

接下来我们需要去实现_resolve,_reject

    _resolve(value){
        if(this._status!==PENDING)// 在pending状态下才能继续
        const run = ()=>{
            const fulfilled = (value)=>{
                let cb
                  while(cb = this._fulfilledQueue.shift()){
                        cb(value)
                    }
            }
            const rejected = (err)=>{
                let cb
                while(cb = this._rejectedQueue.shift()){
                    cb(err)
                }
            }
            if(value instanceof MyPromise){ // 如果参数是一个promise 需要等promise有结果之后在运行
                value.then((value)=>{
                    this._status = FULFILLED
                    this._value = value
                    fulfilled(value)
                },(err)=>{
                    this._status = REJECTED
                    this._value = err
                    rejected(err)
                })
            }else{
                this._status = FULFILLED
                this._value = value
                fulfilled(value)
            }
        }

        setTimeout(()=>{ //异步处理所有问题
            run()
        },0)
    }
    _reject(err){
        if(this._status!==PENDING)
        this._status = REJECTED
        this._value = err
        const rejected = ()=>{
            let cb
            while(cb = this._rejectedQueue.shift()){
                cb(err)
            }
        }
        setTimeout(()=>{
            rejected()
        })
    }