从零实现 promise 的 class 和 function 版本

2023-09-28 09:22:27 浏览数 (2)

Class 版

代码语言:javascript复制
class mPromise {
  // 构造器
  constructor(executor) {
    // 添加属性
    this.PromiseState = "pending";
    this.PromiseResult = null;
    this.callbacks = [];
    const _this = this;

    function resolve(data) {
      if (_this.PromiseState !== "pending") return;
      _this.PromiseState = "fulfilled";
      _this.PromiseResult = data;

      // 执行 then onResolved 回调函数
      setTimeout(() => {
        _this.callbacks.forEach((item) => {
          item.onResolved(data);
        });
      });
    }

    function reject(data) {
      if (_this.PromiseState !== "pending") return;
      _this.PromiseState = "rejected";
      _this.PromiseResult = data;

      // 执行 then onRejected 回调函数
      setTimeout(() => {
        _this.callbacks.forEach((item) => {
          item.onRejected(data);
        });
      });
    }

    try {
      executor(resolve, reject);
    } catch (e) {
      reject(e);
    }
  }

  // then 方法
  then(onResolved, onRejected) {
    const _this = this;

    // 判断回调函数数组中是否是正确的回调函数
    // 用于实现 catch 的异常穿透,添加默认的 onRejected 回调函数
    if (typeof onRejected !== "function") {
      // 如果不是函数,就创建一个函数,抛出异常
      onRejected = (err) => {
        throw err;
      };
    }

    // then 没有指定 onResolved 回调函数,添加默认的 onResolved 回调函数
    if (typeof onResolved !== "function") {
      onResolved = (val) => val;
    }

    return new mPromise((resolve, reject) => {
      // 封装回调函数
      function callback(onResult) {
        try {
          const result = onResult(_this.PromiseResult);
          if (result instanceof mPromise) {
            result.then(
              (val) => {
                resolve(val);
              },
              (err) => {
                reject(err);
              }
            );
          } else {
            resolve(result);
          }
        } catch (e) {
          reject(e);
        }
      }

      // 调用回调函数
      if (this.PromiseState === "fulfilled") {
        setTimeout(() => {
          callback(onResolved);
        });
      }

      if (this.PromiseState === "rejected") {
        setTimeout(() => {
          callback(onRejected);
        });
      }

      if (this.PromiseState === "pending") {
        // 保存回调函数
        // 使用数组保存是为了解决多次调用then方法的问题
        this.callbacks.push({
          onResolved: () => {
            callback(onResolved);
          },
          onRejected: () => {
            callback(onRejected);
          },
        });
      }
    });
  }

  // catch 方法
  catch(onRejected) {
    return this.then(undefined, onRejected);
  }

  // resolve 方法, 是对象方法,不属于实例对象方法
  static resolve(value) {
    return new mPromise((resolve, reject) => {
      if (value instanceof mPromise) {
        value.then(
          (val) => {
            resolve(val);
          },
          (err) => {
            reject(err);
          }
        );
      } else {
        resolve(value);
      }
    });
  }

  // reject 方法, 是对象方法,不属于实例对象方法
  static reject(err) {
    return new mPromise((resolve, reject) => {
      reject(err);
    });
  }

  // all 方法
  static all(promises) {
    return new mPromise((resolve, reject) => {
      let count = 0;
      const arr = [];
      promises.forEach((promise, i) => {
        promise.then(
          (val) => {
            arr[i] = val;
            count  ;
            if (count === promises.length) {
              resolve(arr);
            }
          },
          (err) => {
            reject(err);
          }
        );
      });
    });
  }

  // race 方法
  static race(promises) {
    return new mPromise((resolve, reject) => {
      promises.forEach((promise) => {
        promise.then(
          (val) => {
            resolve(val);
          },
          (err) => {
            reject(err);
          }
        );
      });
    });
  }
}

function 版

代码语言:javascript复制
// 声明构造函数
function mPromise(executor) {
  // 添加属性
  this.PromiseState = "pending";
  this.PromiseResult = null;
  this.callbacks = [];
  const _this = this;

  function resolve(data) {
    if (_this.PromiseState !== "pending") return;
    _this.PromiseState = "fulfilled";
    _this.PromiseResult = data;

    // 执行 then onResolved 回调函数
    setTimeout(() => {
      _this.callbacks.forEach((item) => {
        item.onResolved(data);
      });
    });
  }

  function reject(data) {
    if (_this.PromiseState !== "pending") return;
    _this.PromiseState = "rejected";
    _this.PromiseResult = data;

    // 执行 then onRejected 回调函数
    setTimeout(() => {
      _this.callbacks.forEach((item) => {
        item.onRejected(data);
      });
    });
  }

  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e);
  }
}

mPromise.prototype.then = function (onResolved, onRejected) {
  const _this = this;

  // 判断回调函数数组中是否是正确的回调函数
  // 用于实现 catch 的异常穿透,添加默认的 onRejected 回调函数
  if (typeof onRejected !== "function") {
    // 如果不是函数,就创建一个函数,抛出异常
    onRejected = (err) => {
      throw err;
    };
  }

  // then 没有指定 onResolved 回调函数,添加默认的 onResolved 回调函数
  if (typeof onResolved !== "function") {
    onResolved = (val) => val;
  }

  return new mPromise((resolve, reject) => {
    // 封装回调函数
    function callback(onResult) {
      try {
        const result = onResult(_this.PromiseResult);
        if (result instanceof mPromise) {
          result.then(
            (val) => {
              resolve(val);
            },
            (err) => {
              reject(err);
            }
          );
        } else {
          resolve(result);
        }
      } catch (e) {
        reject(e);
      }
    }

    // 调用回调函数
    if (this.PromiseState === "fulfilled") {
      setTimeout(() => {
        callback(onResolved);
      });
    }

    if (this.PromiseState === "rejected") {
      setTimeout(() => {
        callback(onRejected);
      });
    }

    if (this.PromiseState === "pending") {
      // 保存回调函数
      // 使用数组保存是为了解决多次调用then方法的问题
      this.callbacks.push({
        onResolved: () => {
          callback(onResolved);
        },
        onRejected: () => {
          callback(onRejected);
        },
      });
    }
  });
};

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

// 注意:这里是函数对象方法,不是实例对象方法
mPromise.resolve = function (value) {
  return new mPromise((resolve, reject) => {
    if (value instanceof mPromise) {
      value.then(
        (val) => {
          resolve(val);
        },
        (err) => {
          reject(err);
        }
      );
    } else {
      resolve(value);
    }
  });
};

mPromise.reject = function (err) {
  return new mPromise((resolve, reject) => {
    reject(err);
  });
};

mPromise.all = function (promises) {
  return new mPromise((resolve, reject) => {
    let count = 0;
    const arr = [];
    promises.forEach((promise, i) => {
      promise.then(
        (val) => {
          arr[i] = val;
          count  ;
          if (count === promises.length) {
            resolve(arr);
          }
        },
        (err) => {
          reject(err);
        }
      );
    });
  });
};

mPromise.race = function (promises) {
  return new mPromise((resolve, reject) => {
    promises.forEach((promise) => {
      promise.then(
        (val) => {
          resolve(val);
        },
        (err) => {
          reject(err);
        }
      );
    });
  });
};

0 人点赞