十分钟手写 Promise

2021-07-01  本文已影响0人  前端好有趣

实现代码

// 定义 promise 的三个状态
const PENDING = "pending";
const RESOLVED = "resolved";
const REJECTED = "rejected";

// 创建 Promise 构造函数
function MyPromise(asyncFn) {
  const _this = this;
  // 定义几个内部变量
  _this.state = PENDING;
  _this.value = null;
  _this.resolvedCallbacks = [];
  _this.rejectedCallbacks = [];

  // 定义 resolve 方法
  function resolve(sucValue) {
    if (_this.state === PENDING) {
      _this.state = RESOLVED;
      // 现在获取到成功结果了
      _this.value = sucValue;
      // 然后开始执行获取到成功结果后的 callback 方法
      _this.resolvedCallbacks.map(onResolved => onResolved(_this.value));
    }
  }

  // 定义 reject 方法
  function reject(failValue) {
    if (_this.state === PENDING) {
      _this.state = REJECTED;
      // 现在获取到失败结果了
      _this.value = failValue;
      // 然后开始执行获取到失败结果后的 callback 方法
      _this.rejectedCallbacks.map(onRejected => onRejected(_this.value));
    }
  }

  // 执行 asyncFn 异步方法
  try {
    asyncFn(resolve, reject);
  } catch (e) {
    reject(e);
  }
}

// 定义实例方法 then()
MyPromise.prototype.then = function (onResolved, onRejected) {
  const _this = this;
  const _state = _this.state
  onResolved = typeof onResolved === "function" ? onResolved : (sucValue) => sucValue;
  onRejected = typeof onRejected === "function" ? onRejected : (failValue) => {
    throw failValue;
  };
  switch (_state) {
    case PENDING:
      // 实例处于 PENDING 状态,结果还未确定,将 callback 方法放入队列中,等待 resolve 触发后执行
      _this.resolvedCallbacks.push(onResolved);
      // 实例处于 PENDING 状态,结果还未确定,将 callback 方法放入队列中,等待 reject 触发后执行
      _this.rejectedCallbacks.push(onRejected);
      break;

    case RESOLVED:
      // 实例处于 RESOLVED 状态,结果已确定,直接执行 callback 方法
      onResolved(_this.value);
      break;

    case REJECTED:
      // 实例处于 REJECTED 状态,结果已确定,直接执行 callback 方法
      onRejected(_this.value);
      break;

    default:
      // 状态有误
      break;
  }
};

使用方式

function testPromise(flag) {
  return new MyPromise((resolve, reject) => {
    setTimeout(() => {
      if (flag) {
        resolve("success!");
      } else {
        reject("error!");
      }
    }, 3000);
  });
};

let p = testPromise(true)

p.then(res => {
  console.log(res)
})
上一篇 下一篇

猜你喜欢

热点阅读