一文简单看懂Promise实现原理

Promise 的实现原理基于 状态机 模型,通过管理异步操作的状态来保证代码的正确执行顺序。具体来说,Promise 的实现涉及以下几个关键点:

1. Promise 的三种状态

  • Pending:初始状态,表示操作尚未完成。
  • Fulfilled:表示操作成功完成,且有结果。
  • Rejected:表示操作失败,并且有错误信息。

一个 Promise 在生命周期中只能从 Pending 状态转到 FulfilledRejected,一旦转到这两种状态,它就不会再变化了。

2. Promise 的构造函数

Promise 的构造函数接收一个 executor(执行器)函数,这个函数会立即执行,并接收两个参数:resolvereject。这两个函数用来改变 Promise 的状态,resolve 用来将状态从 Pending 变为 Fulfilledreject 用来将状态变为 Rejected

ini 复制代码
javascript
复制代码
function MyPromise(executor) {
  this.state = "pending"; // 初始状态为 pending
  this.value = undefined;  // 保存成功的结果
  this.reason = undefined; // 保存失败的原因
  this.onFulfilled = []; // 存储 then 的成功回调
  this.onRejected = [];  // 存储 then 的失败回调

  const resolve = (value) => {
    if (this.state === "pending") {
      this.state = "fulfilled";
      this.value = value;
      this.onFulfilled.forEach(callback => callback(value)); // 调用所有成功回调
    }
  };

  const reject = (reason) => {
    if (this.state === "pending") {
      this.state = "rejected";
      this.reason = reason;
      this.onRejected.forEach(callback => callback(reason)); // 调用所有失败回调
    }
  };

  executor(resolve, reject); // 执行执行器函数
}

3. then 方法的实现

then 方法用于处理 Promise 的结果,接收两个参数:一个成功回调(onFulfilled)和一个失败回调(onRejected)。它返回一个新的 Promise,因此可以进行链式调用。

  • 当 Promise 的状态变为 Fulfilled 时,执行 onFulfilled 回调。
  • 当 Promise 的状态变为 Rejected 时,执行 onRejected 回调。
ini 复制代码
javascript
复制代码
MyPromise.prototype.then = function(onFulfilled, onRejected) {
  const self = this;
  return new MyPromise((resolve, reject) => {
    if (self.state === "fulfilled") {
      // 如果当前 Promise 已经完成,直接调用 onFulfilled
      onFulfilled(self.value);
    } else if (self.state === "rejected") {
      // 如果当前 Promise 已经失败,直接调用 onRejected
      onRejected(self.reason);
    } else {
      // 如果还在 pending 状态,存储回调函数
      self.onFulfilled.push(onFulfilled);
      self.onRejected.push(onRejected);
    }
  });
};

4. 链式调用与回调函数的执行

每次调用 then 方法时,都会返回一个新的 Promise,因此可以实现链式调用。此时,then 方法的回调执行时可能会改变 Promise 的状态,这些变化会通过新的 Promise 继续传递下去。

5. 状态不可变性

一旦 Promise 的状态从 Pending 转变为 FulfilledRejected ,它的状态就不可更改,且所有的回调(onFulfilledonRejected)会按顺序执行。如果某个回调函数返回了一个新的 Promise,新的 Promise 会根据返回值的状态决定是执行成功的回调还是失败的回调。

javascript 复制代码
javascript
复制代码
// 示例
const promise = new MyPromise((resolve, reject) => {
  resolve("成功!");
});

promise.then(result => {
  console.log(result); // 输出 "成功!"
  return "继续成功";
}).then(result => {
  console.log(result); // 输出 "继续成功"
});

6. 总结原理

  • Promise 基于 状态机 模式,管理异步操作的状态。
  • 状态变更:从 PendingFulfilledRejected,且不可逆。
  • resolvereject 用于改变 Promise 的状态。
  • then 方法用于处理成功或失败的回调函数,并且可以返回一个新的 Promise 以支持链式调用。
相关推荐
To_OC15 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
To_OC15 小时前
LC 17 电话号码的字母组合:我的回溯算法,就是从这道题开窍的
javascript·算法·leetcode
vipbic15 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy15 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志16 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble17 小时前
c端系统,其实更像一个信息展示平台
前端
你怎么知道我是队长17 小时前
JavaScript的变量和数据类型介绍
开发语言·javascript·ecmascript
李姆斯18 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜18 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司19 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能