前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从零实现 promise 的 class 和 function 版本

从零实现 promise 的 class 和 function 版本

作者头像
白墨石
发布2023-09-28 09:22:27
1410
发布2023-09-28 09:22:27
举报
文章被收录于专栏:生信情报站

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);
        }
      );
    });
  });
};
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Class 版
  • function 版
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档