一文简单看懂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 以支持链式调用。
相关推荐
前端拾光者29 分钟前
利用D3.js实现数据可视化的简单示例
开发语言·javascript·信息可视化
Json_181790144801 小时前
电商拍立淘按图搜索API接口系列,文档说明参考
前端·数据库
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
风尚云网1 小时前
风尚云网前端学习:一个简易前端新手友好的HTML5页面布局与样式设计
前端·css·学习·html·html5·风尚云网
木子02041 小时前
前端VUE项目启动方式
前端·javascript·vue.js
GISer_Jing1 小时前
React核心功能详解(一)
前端·react.js·前端框架
捂月1 小时前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端
深度混淆1 小时前
实用功能,觊觎(Edge)浏览器的内置截(长)图功能
前端·edge
Smartdaili China1 小时前
如何在 Microsoft Edge 中设置代理: 快速而简单的方法
前端·爬虫·安全·microsoft·edge·社交·动态住宅代理
秦老师Q1 小时前
「Chromeg谷歌浏览器/Edge浏览器」篡改猴Tempermongkey插件的安装与使用
前端·chrome·edge