Promise 是异步操作的解决方案,通过状态管理(pending、fulfilled、rejected)实现链式调用与统一错误处理,其核心在于状态不可逆和回调函数的注册与执行机制,手写 MyPromise 可深入理解构造函数、then 方法、resolvePromise 等关键逻辑,结合发布订阅模式和微任务队列模拟异步流程,相比回调函数更清晰可控,且为 async/await 提供底层支持。

Promise 是 J*aScript 中处理异步操作的核心机制之一。它并不是替代回调函数的“新语法”,而是一种更清晰、更可控的异步编程模式。理解 Promise 的实现原理,有助于掌握其运行机制,也能更好地应对复杂的异步流程控制。
Promise 的核心思想
Promise 表示一个异步操作的最终完成或失败,以及其结果值。它的设计目标是解决“回调地狱”(Callback Hell)问题,通过链式调用和统一的错误处理机制提升代码可读性和维护性。
一个原生的 Promise 有三种状态:
- pending(等待中):初始状态,既没有被完成也没有被拒绝
- fulfilled(已成功):操作成功完成
- rejected(已失败):操作失败
状态一旦从 pending 变为 fulfilled 或 rejected,就不可逆,不能再改变。
手写一个简易 Promise
为了理解其实现原理,我们可以实现一个简化版的 Promise,称为 MyPromise。
class MyPromise {
constructor(executor) {
this.status = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.status === 'pending') {
this.status = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : val => val;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };
return new MyPromise((resolve, reject) => {
if (this.status === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(x, resolve, reject);
} catch (e) {
reject(e);
}
});
}
if (this.status === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(x, resolve, reject);
} catch (e) {
reject(e);
}
});
}
if (this.status === 'pending') {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
});
}
}
function resolvePromise(x, resolve, reject) {
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
}
这个简化实现包含了以下关键点:
- 构造函数接收一个执行器(executor),立即执行,并传入 resolve 和 reject 函数
- 通过数组存储异步 resolved 或 rejected 后需要执行的回调(发布订阅模式)
- then 方法支持链式调用,返回新的 Promise 实例
- 使用 setTimeout 模拟微任务队列(实际中 Promise 使用 MutationObserver 或 queueMicrotask)
- resolvePromise 处理返回值可能为 Promise 的情况,实现链式传递
Promise 解决异步问题的优势
相比传统的回调函数,Promise 提供了更优雅的异步解决方案:
微信小程序公众号SaaS管理系统
微信小程序公众号SaaS管理系统是一款完全开源的微信第三方管理系统,为中小企业提供最佳的小程序集中管理解决方案。可实现小程序的快速免审核注册(免300元审核费),可批量发布小程序模板,同步升级版本等功能。基础版本提供商城和扫码点餐两种小程序模板。商户端可以实现小程序页面模块化设计和自动生成小程序源代码并直接发布。
0
查看详情
-
链式调用:避免层层嵌套,代码线性化。例如:
fetch().then(...).then(...).catch() - 统一错误处理:通过 catch 捕获前面任意步骤的异常,无需每个回调都处理错误
- 状态管理清晰:状态不可逆,逻辑更可控
- 可组合性强:支持 Promise.all、Promise.race 等并发控制方法
与 async/await 的关系
async 函数是 Promise 的语法糖。每一个 async 函数返回的都是一个 Promise,而 await 则是 Promise.then 的语法层面封装。
例如:
async function getData() {
const res = await fetch('/api
/data');
const data = await res.json();
return data;
}
等价于:
function getData() {
return fetch('/api/data')
.then(res => res.json());
}
async/await 让异步代码看起来像同步,但底层依然依赖 Promise 实现。
基本上就这些。Promise 不复杂但容易忽略细节,比如状态变更的不可逆性、then 的微任务特性、链式返回的新实例等。掌握其实现原理,能帮助你在复杂场景中写出更健壮的异步逻辑。
以上就是J*aScriptPromise实现原理_J*aScript异步解决方案的详细内容,更多请关注其它相关文章!
# java
# 威海餐饮推广招聘网站
# 线性化
# 更清晰
# 文件上传
# 如何实现
# 键值
# 如何使用
# 可以实现
# 回调
# 链式
# 代码可读性
# ai
# 回调函数
# json
# js
# javascript
# 管理系统
# 捕鱼网站建设教程
# 网站建设规划书 预算
# 安丘seo网络推广
# 韶关市全网推广营销品牌
# 平谷如何做网络营销推广
# 华坪网站优化策略
# 北京模板网站建设公司
# 宝鸡百度seo
# 移动端seo招聘
相关栏目:
【
企业资讯168 】
【
行业动态20933 】
【
网络营销52431 】
【
网络学院91036 】
【
运营推广7012 】
【
科技资讯60970 】
相关推荐:
微信怎么把收藏的内容分类管理 微信收藏内容标签分类方法
c++如何实现一个简单的ECS框架_c++数据驱动设计与游戏开发
圆通快递查询实时追踪 圆通物流包裹状态快速查看
QQ邮箱稳定登录入口_QQ邮箱官方网站网页版使用
Angular Material 垂直步进器:实现底部到顶部排序的教程
Django表单提交验证失败后保持字段值不刷新
知音漫客正版漫画平台_知音漫客官网账号登录
如何更改在 Excel 中打开超链接时的默认浏览器
怎样把文件彻底粉碎无法恢复_Windows下安全删除敏感数据【隐私保护】
如何优雅地扩展SprykerGlue后端API授权逻辑,使用spryker/glue-backend-api-application-authorization-connector-extension
Log4j Console Appender性能瓶颈与高并发优化策略
Win11 USB传输速度慢怎么解决 Win11 USB驱动更新与设置
妖精漫画网页版登录入口免费_妖精漫画官网主页直接阅读漫画
Win11怎么用U盘重装系统 Win11制作启动盘并重装系统完整教程【详解】
Excel如何用迷你图显趋势_Excel用迷你图显趋势【趋势小图】
fishbowl官网免费版 fishbowl养鱼网站入口
win11怎么查看应用耗电情况 Win11电池设置查看应用能耗排行榜【优化】
Spring Boot内嵌服务器与J*a EE全栈特性:选择与部署策略
抖音网页版企业服务中心登录入口_抖音网页版企业登录平台
百度浏览器字体显示异常偏小_百度浏览器字体渲染修复方案
支付宝解绑银行卡步骤_支付宝如何解除绑定银行卡
Golang如何实现Web文件静态资源服务器_Golang静态资源服务器开发与实践
Fabric模组开发:自定义物品与物品组的现代管理方法
解决Django多数据库/多Schema环境下外键迁移问题
HTML5原生日期选择器与jQuery UI:实现日期选择器的联动与程序化控制
mc.js免安装版 mc.js一键畅玩入口
Bing浏览器官方网页版主站 Bing浏览器一键直达链接
Win10磁盘清理工具在哪 Win10打开并使用磁盘清理【教程】
顺丰快件物流信息 官方网站查询入口
移动端XML文件怎么转换成Excel 手机和平板上的解决方案
cad如何更改注释性对象的比例_cad注释性比例调整方法
蛙漫画网页版全站入口 蛙漫热门作品免费浏览
CSS如何设置hover状态颜色_hover伪类调整背景或文字颜色
12306选座怎么选到特殊座位_12306特殊座位选择注意事项
126邮箱手机版登录官网2026_126手机邮箱免费入口最新
php源码怎么在电脑上测试_电脑测试php源码方法步骤【教程】
天眼查企业查询官网入口 天眼查官方网页版查询
漫蛙manwa官网登录界面_漫蛙漫画网页版主站入口
React Hooks最佳实践:动态组件状态管理的组件化方案
豆包手机助手发布技术预览版:直接嵌入手机系统!努比亚样机发售
C#如何安全地从用户上传的XML文件中读取数据? 验证与清理策略
vivo手机互传视频怎么操作_vivo手机互传视频详细传输方法
如何在J*a中使用Locale处理多语言环境
深入理解字体排版:Adobe光学字偶距与CSS字偶距的差异与实现
在React函数组件中利用原生HTML5进行邮箱地址验证
如何为你的Composer包编写自动化测试_集成PHPUnit到Composer的scripts工作流
学习通在线学习平台 学习通网页版直接进入课程中心
在J*aScript中复现SciPy的B样条拟合与求值:关键考量
微信群消息显示延迟如何解决 微信群消息刷新优化方法
手机CPU怎么影响游戏体验_手机CPU对游戏性能的影响分析


/data');
const data = await res.json();
return data;
}
