手写promise

138 阅读2分钟
//步骤一:了解promise规范
//步骤二:实现
//步骤三:测试
const statusMap = {
  PENDING: "pending",
  FULFILLED: "fulfilled",
  REJECTED: "rejected",
};
//将promise设置为fulfilled状态
function fulfilledPromise(promise, value) {
  //只能从pending状态转换为其他状态
  if (promise.status !== statusMap.PENDING) {
    return;
  }
  promise.status = statusMap.FULFILLED;
  promise.value = value;
  runCbs(promise.fulfilledCbs, value);
}
//将promise设置为rejected状态
function rejectedPromise(promise, reason) {
  //只能从pending状态转换为其他状态
  if (promise.status !== statusMap.PENDING) {
    return;
  }
  promise.status = statusMap.REJECTED;
  promise.reason = reason;
  runCbs(promise.rejectedCbs, value);
}
function runCbs(cbs, value) {
  //上一个promise的value
  cbs.forEach((cb) => cb(value));
}
function isFunction(fn) {
  return (
    Object.prototype.toString.call(fn).toLocaleLowercase() ===
    "[object function]"
  );
}
function isObject(obj) {
  return (
    Object.prototype.toString.call(obj).toLocaleLowercase() === "[object object]"
  );
}
function isPromise(p) {
  return p instanceof Promise;
}
//promise的解析
function resolvePromise(promise, x) {
  //todo
  //如果是promise和x指向相同的值
  if (promise === x) {
    rejectedPromise(promise, new TypeError("不能是一个相同的值"));
    return;
  }

  //如果x是一个promise
  if (isPromise(x)) {
    if (x.status === statusMap.FULFILLED) {
      fulfilledPromise(promise, x.value);
      return;
    }
    if (x.status === statusMap.REJECTED) {
      rejectedPromise(promise, x.value);
      return;
    }
    if (x.status === statusMap.PENDING) {
      x.then(
        () => {
          fulfilledPromise(promise, x.value);
        },
        () => {
          rejectedPromise(promise, x.value);
        }
      );
      return;
    }
    return;
  }
  //如果x是一个对象或一个函数
  if (isObject(x) || isFunction(x)) {
    let then;
    let called = false;
    try {
      //兼容then方法
      then = x.then;
    } catch (error) {
      rejectedPromise(promise, error);
      return;
    }
    if (isFunction(then)) {
      try {
        then.call(
          x,
          (y) => {
            if (called) {
              return;
            }
            called = true;
            resolvePromise(promise, y);
          },
          (r) => {
            if (called) {
              return;
            }
            called = true;
            rejectedPromise(promise, r);
          }
        );
      } catch (error) {
        if (called) {
          return;
        }
        called = true;
        rejectedPromise(promise,error);
      }
      return;
    } else {
      fulfilledPromise(promise, x);
      return;
    }
  } else {
    //如果x不是对象也不是函数
    fulfilledPromise(promise, x);
    return;
  }
}
class Promise {
  constructor(fn) {
    this.status = statusMap.PENDING; //默认状态
    this.value = undefined;
    this.reason = undefined;
    this.fulfilledCbs = []; //then fulfilled callback
    this.rejectedCbs = []; //then rejected callback
    fn(
      (value) => {
       // fulfilledPromise(this, value);
       resolvePromise(this,value);
      },
      (reason) => {
        rejectedPromise(this, reason);
      }
    );
  }
  //两个参数
  then(onFulfilled, onRejected) {
    const promise1 = this;
    const promise2 = new P(() => {});
    if (promise1.status === statusMap.FULFILLED) {
      //判断状态fulfilled是不是一个function
      if (!isFunction(onFulfilled)) {
        //生成新promise和老的pronmise是一样的
        return promise1;
      }
      setTimeout(() => {
        try {
          const x = onFulfilled(promise1.value); //产生一个值
          resolvePromise(promise2, x); //最终决定状态
        } catch (error) {
          rejectedPromise(promise2, error);
        }
      }, 0); //模拟异步执行过程
    }
    if (promise1.status === statusMap.REJECTED) {
      //判断状态rejected是不是一个function
      if (!isFunction(onRejected)) {
        //生成新promise和老的pronmise是一样的
        return promise1;
      }
      setTimeout(() => {
        try {
          const x = onRejected(promise1.value); //产生一个值
          resolvePromise(promise2, x); //最终决定状态
        } catch (error) {
          rejectedPromise(promise2, error);
        }
      }, 0); //模拟异步执行过程
    }
    if (promise1.status === statusMap.PENDING) {
        onFulfilled= isFunction(onFulfilled)?onFulfilled:(value)=>{
            return value;
        }
        onRejected=isFunction(onRejected)?onRejected:(err)=>{
            throw err;
        }
      promise1.fulfilledCbs.push(() => {
        setTimeout(() => {
          try {
            const x = onFulfilled(promise1.value); //产生一个值
            resolvePromise(promise2, x); //最终决定状态
          } catch (error) {
            rejectedPromise(promise2, error);
          }
        }, 0);
      });
      promise1.rejectedCbs.push(() => {
        setTimeout(() => {
          try {
            const x = onRejected(promise1.reason); //产生一个值
            resolvePromise(promise2, x); //最终决定状态
          } catch (error) {
            rejectedPromise(promise2, error);
          }
        }, 0);
      });
    }
    return promise2;
  }
}

//钩子函数暴露出来 测试用到的钩子
Promise.deferred=function(){
    const deferred={};
    deferred.promise=new Promise((resolve,reject)=>{
        deferred.resolve=resolve;
        deferred.reject=reject;
    })
    return deferred;
};
module.exports=Promise;