手写Promise

71 阅读2分钟

传统方式

//状态管理
const state = {
  pending : 'pending',
  fulfilled:'fulfilled',
  rejected:'rejected'
};
function Promise(executor) {
  //添加属性
  this.PromiseState = state.pending;
  this.PromiseResult = null;
  this.callBacks = [];//用于执行异步任务的队列
  const setState = (type, data) => {
    if (this.PromiseState !== state.pending) return;//状态修改只有一次
    this.PromiseState = type;
    this.PromiseResult = data;
    setTimeout(() => {
      //异步任务执行的回调函数
      this.callBacks.forEach(callBack => {
        callBack[type](this.PromiseResult);
      });
    })
  }
  const resolve = (data) => setState(state.fulfilled, data);
  const reject = (data) => setState(state.rejected, data);
  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e);
  }
}
Promise.prototype.then = function (fulfilled, rejected) {
  //传入的参数是空的时候主动补全
  if (typeof rejected !== 'function') rejected = reason => { throw reason };
  if (typeof fulfilled !== 'function') fulfilled = value => value;
  const self = this;
  return new Promise((resolve, reject) => {
    const callBack = (type) => {
      try {
        let result = type(self.PromiseResult);
        if (result instanceof Promise) {
          result.then(v => {
            resolve(v);
          }, r => {
            reject(r);
          })
        } else {
          resolve(result);
        }
      } catch (e) {
        reject(e);
      }
    }

    if (this.PromiseState == state.fulfilled) setTimeout(() => callBack(fulfilled));
    if (this.PromiseState == state.rejected) setTimeout(() => callBack(rejected));
    if (this.PromiseState == state.pending) this.callBacks.push({ fulfilled: () => callBack(fulfilled), rejected: () => callBack(rejected) })
  })
}

Promise.prototype.catch = function(onRejected){
  return this.then(undefined, onRejected);
}

//添加 resolve 方法
Promise.resolve = function(value){
  //返回promise对象
 return new Promise((resolve,reject)=>{
   if(value instanceof Promise){
     value.then(r=>resolve(r),r=>reject(r));
   }else{
     resolve(value);
   }
 })
}
//添加 reject 方法
Promise.reject = function(reason){
  return new Promise((resolve, reject)=>{
      reject(reason);
  });
}

//添加 all 方法
Promise.all = function(promises){
  return new Promise((resolve,reject)=>{
    let arr=[];
    let count=0;
    let len=promises.length;
    for(let i=0;i<len;i++){
      promises[i].then(data=>{
        count++;
        arr[i]=data;
        if(count==len){
          resolve(arr);
        }
      },err=>reject(err));
    }
  })
}
//添加race方法
Promise.race=promises=>new Promise((resolve,reject)=>{
  for(let p of promises){
    p.then(r=>resolve(r),r=>reject(r));
  }
})

类式结构


const state = {
  pending: 'pending',
  fulfilled: 'fulfilled',
  rejected: 'rejected'
}
class Promise {
  PromiseState = state.pending;
  PromiseResult = null;
  callBacks = [];
  setState = (type, data) => {
    if (this.PromiseState !== state.pending) return;
    this.PromiseResult = data;
    this.PromiseState = type;
    //异步任务回调函数的执行
    setTimeout(() => {
      this.callBacks.forEach(callback => {
        callback[type](data);
      })
    })
  }
  reject = data => this.setState(state.rejected, data);
  resolve = data => this.setState(state.fulfilled, data);
  constructor(executor) {
    try {
      executor(this.resolve, this.reject);
    } catch (e) {
      this.reject(e);
    }
  }
  then = (fulfilled, rejected) => {
    //链式调用v;
    if (typeof fulfilled !== 'function') fulfilled = v => v;
    if (typeof rejected !== 'function') rejected = v => { throw v };
    return new Promise((resolve, reject) => {
      //如果返回的是promise则进行继承
      const cb = (type) => {
        try {
          let result = type(this.PromiseResult);
          if (result instanceof Promise) {
            result.then(r => resolve(r), r => reject(j))
          } else {
            resolve(result)
          }
        } catch (e) { reject(e) }

      }
      if (this.PromiseState == state.fulfilled) setTimeout(() => cb(fulfilled))
      if (this.PromiseState == state.rejected) setTimeout(() => cb(rejected))
      if (this.PromiseState == state.pending) this.callBacks.push({
        fulfilled: () => cb(fulfilled),
        rejected: () => cb(rejected)
      });
    })
  }
  catch = (rejected) => {
    return this.then(null, rejected);
  }
  static all = (promises) => {
    return new Promise((resolve, reject) => {
      let count = 0;
      let len = promises.length;
      let arr = [];//结果
      for (let i = 0; i < len; i++) {
        promises[i].then(r => {
          count++; arr[i] = r;
          if (len == count) resolve(arr);
        }, r => reject(r));
      }
    })
  }
  static race = (promises) => new Promise((resolve, reject) => {
    for (let p of promises) {
      p.then(r => resolve(r), r => reject(r));
    }
  })
}