mypromise: 深入理解JavaScript中的Promise简易实现
需积分: 11 60 浏览量
更新于2024-12-02
收藏 3KB ZIP 举报
在现代JavaScript编程中,Promise是一个非常重要的异步编程抽象。它代表了一个异步操作的最终完成或失败及其结果值。Promise对象有三种状态:pending(等待中)、fulfilled(已成功)和rejected(已失败)。
在本节内容中,我们将探讨如何实现一个简单的Promise对象,命名为“mypromise”。这样的实现有助于深入理解Promise的工作原理,包括它的状态管理、异步任务的调度以及then方法的链式调用等。
首先,我们需要了解Promise的构造函数。Promise构造函数接受一个执行器(executor)函数作为参数,该函数有两个参数:resolve和reject。这两个参数同样是函数,由JavaScript引擎提供。resolve函数用于将Promise对象的状态从"pending"变为"fulfilled",而reject函数则将状态从"pending"变为"rejected"。
```javascript
function myPromise(executor) {
let _status = 'pending'; // 初始状态
let _value = null; // 成功的值
let _reason = null; // 失败的原因
let _onFulfilledCallbacks = []; // 成功回调队列
let _onRejectedCallbacks = []; // 失败回调队列
// 成功时调用的函数
function resolve(value) {
if (_status === 'pending') {
_status = 'fulfilled';
_value = value;
_onFulfilledCallbacks.forEach(fn => fn(_value));
}
}
// 失败时调用的函数
function reject(reason) {
if (_status === 'pending') {
_status = 'rejected';
_reason = reason;
_onRejectedCallbacks.forEach(fn => fn(_reason));
}
}
// 抛出一个异常来调用reject
function throwException(error) {
reject(error);
}
try {
executor(resolve, reject); // 同步执行executor
} catch (e) {
throwException(e); // 捕获异常,调用reject
}
}
```
接下来,我们需要在mypromise中实现then方法,它用于注册Promise成功或失败的回调函数。then方法需要支持链式调用,即返回一个新的Promise对象,以便我们可以将多个异步操作串联起来。
```javascript
myPromise.prototype.then = function(onFulfilled, onRejected) {
// 如果onFulfilled不是函数,默认传入一个返回value的函数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
// 如果onRejected不是函数,默认传入一个抛出reason的函数
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
let promise2 = new myPromise((resolve, reject) => {
if (_status === 'fulfilled') {
setTimeout(() => {
try {
let x = onFulfilled(_value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (_status === 'rejected') {
setTimeout(() => {
try {
let x = onRejected(_reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (_status === 'pending') {
_onFulfilledCallbacks.push((value) => {
setTimeout(() => {
try {
let x = onFulfilled(value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
_onRejectedCallbacks.push((reason) => {
setTimeout(() => {
try {
let x = onRejected(reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
};
function resolvePromise(promise2, x, resolve, reject) {
// 如果相等则报错
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
let called;
// x不是null 且x是对象或函数
if (x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
}, r => {
if (called) return;
called = true;
reject(r);
});
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}
```
以上代码展示了mypromise的核心实现,包括构造函数、状态转换、异步回调以及链式调用等。通过这种简易的实现,开发者可以更深入地理解Promise的工作机制。在实际的项目开发中,我们通常会直接使用JavaScript内置的Promise对象,因为内置的Promise更完善、健壮并且在现代浏览器中得到原生支持。然而,亲手实现Promise不仅可以增进对异步编程的理解,还能够提升解决问题和处理复杂情况的能力。
点击了解资源详情
点击了解资源详情
101 浏览量
101 浏览量
点击了解资源详情
109 浏览量
2021-07-14 上传
2021-07-14 上传
2020-12-09 上传
牟云峰
- 粉丝: 22
最新资源
- Qt多类型输入对话框库InputFormDialog教程
- JavaScript日历组件的使用与自定义渲染
- 纯CSS实现红色高亮效果的网站导航菜单
- VK视频播放一次后自动停止的CRX插件功能介绍
- C#与SQL SERVER图书管理系统开发教程
- 深入理解JavaScript实用技巧与实战演练
- Termius CLI:跨平台SSH客户端命令行工具
- 剪影效果的Flash乐队演奏动画资源
- Web出版物注释扩展规范的资料库与协作指南
- 全面解析stm32驱动OLED显示屏技术资料
- 深入研究DALC人工智能技术的JupyterNotebook实践
- 打造简洁优雅的圆形Android菜单界面
- microlog:Node.js微服务器端日志记录器的使用和特性
- Three.js进阶指南:掌握BufferGeometry的贴图属性
- 探索旧Macintosh ROM文件:Macintosh-ROMs-master
- 全面解析CRMEB知识付费源码v1.2版功能特点