乐趣区

关于前端:手动实现-Promise

Promise 代表了一个异步操作的最终实现或者失败

定义状态

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

构造函数定义


function MyPromise(excutor) {
  // 初始状态为 pending
  this.status = PENDING;
  // 胜利的值
  this.value = undefined;
  // 失败的起因
  this.reason = undefined;
  // then 的回调函数汇合
  this.fulfilledCallback = [];
  this.rejectedCallback = [];

  const resolve = (value) => {if (this.status === PENDING) {
      this.status = FULFILLED;
      this.value = value;
      setTimeout(() => {
        // 状态变更后执行 then 的回调函数
        this.fulfilledCallback.forEach((fn) => fn(value));
      });
    }
  };

  const reject = (reason) => {if (this.status === PENDING) {
      this.status = REJECTED;
      this.reason = reason;
      setTimeout(() => {this.rejectedCallback.forEach((fn) => fn(reason));
      }, 0);
    }
  };

  try {excutor(resolve, reject);
  } catch (error) {reject(error);
  }
}

原型办法

MyPromise.prototype.then = function (onResolve, onReject) {(onResolve = onResolve === undefined ? (value) => value : onResolve),
    (onReject =
      onReject === undefined
        ? (error) => {throw error;}
        : onReject);

  return new MyPromise((resolve, reject) => {function handle(func, value) {
      try {const result = func(value);
        // 如果返回一个 Promise
        if (result instanceof MyPromise) {result.then(resolve, reject);
        } else {resolve(result);
        }
      } catch (err) {reject(err);
      }
    }

    if (this.status === FULFILLED) {setTimeout(() => {handle(onResolve, this.value);
      });
    }

    if (this.status === REJECTED) {setTimeout(() => {handle(onReject, this.reason);
      });
    }

    // 状态为 pending,将回调函数保留到后面定义的函数汇合中
    if (this.status === PENDING) {
      // 保留到 fulfilledCallback
      this.fulfilledCallback.push((value) => {handle(onResolve, value);
      });

      // 保留到 rejectedCallback
      this.rejectedCallback.push((reason) => {handle(onReject, reason);
      });
    }
  });
};

MyPromise.prototype.catch = function (onReject) {return this.then(undefined, onReject);
};

MyPromise.prototype.finally = function (cb) {
  return this.then((value) => MyPromise.resolve(cb()).then(() => value),
    (reason) =>
      MyPromise.resolve(cb()).then(() => {throw reason;})
  );
};

静态方法

MyPromise.resolve = function (value) {
  // 如果参数是 MyPromise 实例,间接返回这个实例
  if (value instanceof MyPromise) return value;
  return new MyPromise((resolve) => resolve(value));
};

MyPromise.reject = function (value) {
  // 如果参数是 MyPromise 实例,间接返回这个实例
  if (value instanceof MyPromise) return value;
  return new MyPromise((resolve, reject) => reject(value));
};

MyPromise.race = function (promises) {return new Promise((resolve, reject) => {promises.forEach((p) => {MyPromise.resolve(p).then(resolve, reject);
    });
  });
};

MyPromise.all = function (promises) {let result = [];
  const len = promises.length;
  return new MyPromise((resolve, reject) => {promises.forEach((p, index) => {MyPromise.resolve(p).then((res) => {result[index] = res;
          if (result.length === len) {resolve(result);
          }
        },
        (error) => {reject(error);
        }
      );
    });
  });
};

MyPromise.allSettled = function (promises) {let result = [];
  const len = promises.length;
  return new MyPromise((resolve, reject) => {promises.forEach((p, index) => {MyPromise.resolve(p).then((value) => {result[index] = {
            status: FULFILLED,
            value,
          };
          if (result.length === len) {resolve(result);
          }
        },
        (reason) => {result[index] = {
            status: REJECTED,
            reason,
          };
          if (result.length === len) {resolve(result);
          }
        }
      );
    });
  });
};
退出移动版