手写Promise-构造函数

在上篇手写Promise-什么是Promise中,我们已经了解了Promise的基本概念和用法。本文将开始用ES5的语法手写Promise的实现,首先从构造函数部分开始讲解。

基础结构搭建

在上篇手写Promise-什么是Promise已经了解到Promise是一个构造函数,接收一个executor参数并立即执行。executor接收两个参数:resolvereject,都是函数类型。可以写成如下代码:

js 复制代码
(function () {
  // 开启严格模式
  "use strict";
  function Promise(executor) {
    // 存储this,方便后续使用
    var self = this;
    // resolve函数接收一个操作成功后的值
    var resolve = function (value) {};
    // reject函数接收一个操作失败的原因
    var reject = function (reason) {};
    executor(resolve, reject);
    // 暴露给浏览器
    if (typeof window !== "undefined") {
      window.Promise = Promise;
    }
    // 暴露给Node.js环境
    if (typeof module === "object" && typeof module.exports === "object") {
      module.exports = Promise;
    }
  }
})();

状态管理

Promise需要记录当前操作的状态(pendingfulfilledrejected)以及操作结果。状态一旦改变就不可逆转 ,这是Promise的重要特性。还需要存储操作成功时的值或操作失败的原因。为result

js 复制代码
(function () {
  "use strict";
  function Promise(executor) {
    // 存储this,方便后续使用
    var self = this;
    // 状态常量
    var PENDING = "pending";
    var FULFILLED = "fulfilled";
    var REJECTED = "rejected";
    self.state = PENDING; // 初始状态
    self.result = void 0;
    // resolve函数接收一个操作成功后的值
    var resolve = function (value) {};
    // reject函数接收一个操作失败的原因
    var reject = function (reason) {};
    executor(resolve, reject);
  }
})();

异常处理

executor可能出现异常,需要捕获并将状态改为rejected。所以捕获到需要执行reject函数。

js 复制代码
(function () {
  // 开启严格模式
  "use strict";
  function Promise(executor) {
    /* 代码省略 */
    // resolve函数接收一个操作成功后的值
    var resolve = function (value) {};
    // reject函数接收一个操作失败的原因
    var reject = function (reason) {};
    try {
      executor(resolve, reject);
    } catch(error) {
      reject(error);
    }
  }
})();

特别注意: try-catch这里无法捕获异步操作的异常。例如以下代码:

js 复制代码
var p = new Promise((resolve) => {
    setTimeout(() => {
        throw new Error(111)
    })
})

参数合法性校验

为了代码健壮性,对参数executor进行校验。

js 复制代码
(function () {
  // 开启严格模式
  "use strict";
  function Promise(executor) {
    // 存储this,方便后续使用
    var self = this;
    /* 代码省略 */
    if (typeof executor !== "function") {
      // 不是函数但是一个对象的报错
      if (typeof executor === "object" && executor !== null) {
        throw new TypeError(
          "TypeError: Promise resolver #<Object> is not a function"
        );
      }
      // 不是一个函数的报错
      throw new TypeError(`Promise resolver ${executor} is not a function`);
    }
    // 构造函数调用检查 - 必须通过new方式调用
    if (!(self instanceof Promise)) {
      throw new TypeError(
        `Promise constructor cannot be invoked without 'new'`
      );
    }
    /* 其余代码 */
  }
})();

初步实现resolve和reject函数

resolve和reject函数分别是成功和失败时调用的。同时当状态是pending时进行修改成对应的状态。

js 复制代码
var resolve = function (value) {
  // 防止后续继续调用resolve或reject
  if (self.state !== PENDING) return;
  self.state = FULFILLED;
  self.result = value;
};
var reject = function (reason) {
  // 防止后续继续调用resolve或reject
  if (self.state !== PENDING) return;
  self.state = REJECTED;
  self.result = reason;
};

小结

本文实现的Promise构造函数具有以下特点:

✅ 已实现功能

  1. 基本结构:完整的构造函数框架
  2. 状态管理:三种状态(pending/fulfilled/rejected)的管理
  3. 状态不可逆:确保状态只能改变一次
  4. 异常处理:同步错误的捕获机制
  5. 参数校验:严格的类型和调用方式检查
  6. 环境适配:浏览器和Node.js环境支持

🎯 下一阶段目标

下一篇文章将实现Promise的核心------then方法,包括:

  • 回调函数的异步执行
  • 链式调用支持
  • 值穿透机制 希望对你有些许帮助!┏(^0^)┛
相关推荐
fruge1 小时前
Vue项目中的Electron桌面应用开发实践指南
前端·vue.js·electron
漂流瓶jz7 小时前
Webpack中各种devtool配置的含义与SourceMap生成逻辑
前端·javascript·webpack
这是个栗子7 小时前
【问题解决】用pnpm创建的 Vue3项目找不到 .eslintrc.js文件 及 后续的eslint配置的解决办法
javascript·vue.js·pnpm·eslint
前端架构师-老李7 小时前
React 中 useCallback 的基本使用和原理解析
前端·react.js·前端框架
木易 士心8 小时前
CSS 中 `data-status` 的使用详解
前端·css
明月与玄武8 小时前
前端缓存战争:回车与刷新按钮的终极对决!
前端·缓存·回车 vs 点击刷新
牧马少女8 小时前
css 画一个圆角渐变色边框
前端·css
zy happy8 小时前
RuoyiApp 在vuex,state存储nickname vue2
前端·javascript·小程序·uni-app·vue·ruoyi
小雨青年9 小时前
Cursor 项目实战:AI播客策划助手(二)—— 多轮交互打磨播客文案的技术实现与实践
前端·人工智能·状态模式·交互
Nan_Shu_6149 小时前
学习:JavaScript(5)
开发语言·javascript·学习