纯手写promise

156 阅读1分钟

Promise

class Promisem{
    constructor(executor){
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;
        this.onResolvedCallbacks=[]
        this.onRejectedCallbacks=[]
        this.resolve = this.resolve.bind(this)
        this.reject = this.reject.bind(this)
        this.finally=this.finally.bind(this)
        this.then=this.then.bind(this)
        try{
            executor(this.resolve, this.reject)         
        }catch(e){
            this.reject(e)
        }
        
   }
 resolve(value){
   if(this.state === 'pending'){
       this.value = value;
       this.state = 'fulfilled' 
    while (this.onResolvedCallbacks.length>0){
         this.onResolvedCallbacks.shift()()
    }           }
  }
 reject(reason){
    if(this.state === 'pending'){
        this.reason= reason;
        this.state = 'rejected'
      while (this.onRejectedCallbacks.length>0){
        this.onRejectedCallbacks.shift()()
      }
     }
  }
 finally(callback) {
    let P = this.constructor; //P.resolve(callback())
    return this.then(
                value  => new Promisem((res,rej)=>{res(callback())}).then(() => value),
                reason => new Promisem((res,rej)=>{res(callback())}).then(() => { throw reason })     );}
 then(onFulfilled='', onRejected=''){
    console.log(this.state)
    let P = this.constructor; 
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled :value=>value;
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason};
    
    if(this.state === 'fulfilled'){
       return  new Promisem((res,rej)=>{res(onFulfilled(this.value))})
    }else if(this.state === 'rejected'){           return  new Promisem((res,rej)=>{rej(onRejected(this.reason))})     
    }else{
         this.onResolvedCallbacks.push(()=>{              let x = onResolve(this.value)
              if(x instanceof Promisem){
                  x.then((res)=>{new Promisem((r)=>{r(res)})},(err)=>{new Promisem((r,j)=>{j(err)})})
              }else{
                  new Promisem(r=>r(x))
              }            })

            this.onRejectedCallbacks.push(()=>{
              let x = onReject(this.reason)
              if(x instanceof Promisem){
                  x.then((res)=>{new Promisem((r)=>{r(res)})},(err)=>{new Promisem((r,j)=>{j(err)})})
              }else{
                  new Promisem(r=>r(x))
              }           })
    }
  }

}

Promise.resolve  参数类型=>[ ‘值’, promise实例, thenable, 空]

Promise.resolve = function (value) {
    //if (value && typeof value === "object" && value instanceof Promise) {
   if (value && typeof value === "object" 
&& typeof value.catch === 'function' && typeof value.then === 'function') {        
        return value;
    }
    return new Promise((res) => res(value));
};

_Promise.reject _ 返回一个带有拒绝原因的Promise对象

Promise.reject = function (value) {
    return new Promise((_, reject) => {
        reject(value);
    });
};

Promise.all  返回全部fulfilled结果数组或者首个rejected结果

Promise.all = function (promises) {
  return new Promise((res, rj) => {
    promises = Array.from(promises)
    const len = promises.length;
    if (len === 0) {
      return res([]);
    }
    const arr = [];
    promises.forEach((promise, i) => {
      Promise.resolve(promise)
      .then((res1) => {
          arr[i] = res1;
          if (i === len - 1) {
            res(arr);
          }
      })
      .catch(rj);
    });
  });
};

Promise.allSettled 不管是fulfilled还是rejected全部返回

Promise.allSettled = function (promises) {
 return new Promise((res, rj) => {
        promises = Array.from(promises);
        const len = promises.length;
        if (len === 0) {
            res([]);
        }
        const arr = [];
        let count = 0;
    if (p && typeof p.then === 'function') {
        promises.forEach((promise, i) => {            Promise.resolve(promise)
            .then((r) => {
                ++count;
                arr[i] = {status:'fulfilled', value: r };
                if (count === len) {
                    res(arr);
                }
            })
            .catch((err) => {
                ++count;                
                arr[i] = {
                    status: "rejected",
                    reason: err,
                };
                if (count === len) {
                    res(arr);
                }
            });
        });
    }else{
       ++count;
       arr[i] = {status:'fulfilled', value: r };        
        if (count === len) {
                res(arr);
        }    
    }
        
 });
};

Promise.race  返回最新rejected或者fulfilled的那一个结果

Promise.race = function (promises) {
    return new Promise((res, rj) => {
        promises = Array.from(promises);
        promises.forEach(promise=>{
            Promise.resolve(promise).then(res).catch(rj);        })
    });
};

Promise.any 返回最新fulfilled,或者全部rejected的结果

Promise.any= function (promises) {
    return new Promise((res, rj) => {
        promises = Array.from(promises);
        let count = 0;
        promises.forEach((promise,index)=>{
            Promise.resolve(promise).then(res).catch((e)=>{
                ++count;
                if(count===promises.length){
                    rj('All promises were rejected')
                }
            });
        })
    });
};