带你手撕Promise(全文无废话)

  • Post author:
  • Post category:其他




手撕

Promise

//定义状态
const PROMISE_STATUS_PENDING = 'pending';
const PROMISE_STATUS_FULFILLED = 'fulfilled';
const PROMISE_STATUS_REJECTED = 'rejected';

//工具函数
function executorWithCatchError(execFn, value, resolve, reject){
  try{
    const result = execFn(value);
    resolve(result);
  } catch(err){
      reject(err);
  }
}

class TestPromise{
  constructor(executor){
    this.status = PROMISE_STATUS_PENDING;
    this.value = undefined;
    this.reason = undefined;
    this.onFulfilledFns = [];
    this.onRejectedFns = [];
      
    //实现resolve方法
    const resolve = () => {
      if(this.status = PROMISE_STATUS_PENDING){
        //添加微任务
        queueMicrotask(() => {
          if(this.status !== PROMISE_STATUS_PENDING) return;
          this.status = PROMISE_STATUS_FULFILLED;
          this.value = value;
          this.onFulfilledFns.forEach(fn =>{
          	fn(this.value); 
          })
        });
      }
    }
    
    //实现reject方法
    const reject = (reason) =>{
      if(this.status = PROMISE_STATUS_FULFILLED){
        //添加微任务
        queueMicrotask(() => {
          if(this.status !== PROMISE_STATUS_PENDING) return ;
          this.status = PROMISE_STATUS_REJECTED;
          this.reason = reason;
          this.onRejectedFns.forEach(fn => {
            fn(this.reason);
          })
        });
      }
    }
    
    try{
      exector(resolve, reject);
    } catch(err){
      reject(err);
    }
      
    //实现then方法
    then(onFulfilled, onRejected){
      const defaultOnRejected = err =>{throw err}
      onRejected = onRejected || defaultOnRejected;
      
      const defaultFulfilled = value =>{return value}
      onFulfilled = onFulfilled || defaultFulfilled;
        
      return new TestPromise((resolve, reject) => {
        //如果在then调用的时候,状态已经确定下来
        if(this.status === PROMISE_STATUS_FULFILLED && onfulfilled){
          executorWithCatchError(onFulfilled, this.value, resolve, reject);
        }
        if(this.status === PROMISE_STATUS_REJECTED && onRejected){
          executorWithCatchError(onRjected, this.reason, resolve, reject);
        }
          
        //将成功回调和失败回调放在数组中
        if(this.status === PROMISE_STATUS_PENDING){
          if(onfulfilled) this.onFulfilledFns.push(()=> {
            executorWithCatchError(onFulfilled, this.value, resolve, reject);
          })
          if(onRejected) this.onRejectedFns.push(() => {
            executorWithCatchError(onRjected, this.reason, resolve, reject);
          })
        }
      })
    }
    
    //实现catch方法
    catch(onRejected){
      return this.then(undefined, onRejected);
    }
      
    //实现finaly方法
    finaly(onFinaly){
      this.then(() => {
        onFinaly();
      }, () => {
        onFianly();
      })
    }
      
    //实现resolve方法
    static resolve(value){
      return new TestPromise((reason) => resolve(value));
    }
      
    //实现reject方法
    static reject(reason){
      return new TestPromise((resolve, reject) => reject(reason));
    }
      
    //实现all方法
    static all(promises){
      //注意什么时候回调resolve,什么时候回调reject
      return new TestPromise((resolve, reject) => {
        const values = [];
        promises.forEach(promise => {
          promise.then(res => {
            values.push(res);
            if(values.length === promises.length){
              resolve(values);
            }
          }, err => {
              reject(err);
          })
        })
      })
    }
      
    //实现allSetted方法
    static allSetted(promises) {
      const results = [];
      promise.forEch(promise => {
        promise.then(res => {
          results.push({ status:PROMISE_STATUS_FULFILLED, value:res });
          if(results.length === promises.length){
            resolve(results);
          }
        }, err =>{
            results.push({ status:PROMISE_STATUS_REJECTED, value:err });
            if(results.length === promises.length){
              resolve(results);
            }
          })
        })
      })
    }
      
    //实现race方法
    static race(promises){
      return new TestPromise((resolve, rejetc) => {
        promises.forEach(promise => {
          promise.then(resolve, reject);
        })
      })
    }
    
    //实现any方法
    static any(promises){
      const reasons = [];
      promises.forEach(promise => {
        promise.then(resolve, err =>{
          reasons.push(err);
          if(reasons.length === promises.length){
            reject(new AggregateError(reasons));
          }
        })
      })
    }
    
  }
}



版权声明:本文为Noria107原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。