深入浅出手写JavaScript Promise
需积分: 9 200 浏览量
更新于2024-12-13
收藏 1KB ZIP 举报
资源摘要信息: "js代码-手写Promise"
在前端开发领域,Promise是处理异步操作的一种强大工具,它让异步代码的组织和错误处理更加清晰和优雅。Promise 的核心思想是通过一个代表了异步操作最终完成或失败的对象,将异步操作的未来完成或失败状态与对应的处理方法关联起来。在 JavaScript 中,Promise 是一个内置对象,但了解如何从头开始手写一个 Promise 对象,对于深入理解其工作原理和设计模式具有重要意义。
Promise对象有三种状态:pending(等待中)、fulfilled(已成功)和rejected(已失败)。一个Promise从pending开始,然后根据异步操作的结果,要么转换为fulfilled,要么转换为rejected。
以下是一个手写Promise的示例代码,包含了Promise构造函数、then方法和catch方法的核心实现。
```javascript
class MyPromise {
// Promise构造函数接受一个执行函数,该执行函数接受两个参数,resolve和reject
constructor(executor) {
this.state = 'pending'; // 初始状态
this.value = null; // 成功时的返回值
this.reason = null; // 失败时的原因
this.onFulfilledCallbacks = []; // 成功回调队列
this.onRejectedCallbacks = []; // 失败回调队列
// 成功时调用的方法
let resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn(this.value));
}
};
// 失败时调用的方法
let reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn(this.reason));
}
};
try {
executor(resolve, reject); // 立即执行传入的执行函数
} catch (error) {
reject(error); // 如果执行函数抛出异常,Promise立即变为rejected状态
}
}
// Promise原型上的then方法
then(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };
let promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
// 创建一个微任务等待promise2完成初始化
queueMicrotask(() => {
try {
let x = onFulfilled(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
} else if (this.state === 'rejected') {
// 同样创建微任务等待promise2完成初始化
queueMicrotask(() => {
try {
let x = onRejected(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
} else if (this.state === 'pending') {
// 当异步操作未完成时,将回调函数保存到对应回调数组中
this.onFulfilledCallbacks.push((value) => {
try {
let x = onFulfilled(value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
this.onRejectedCallbacks.push((reason) => {
try {
let x = onRejected(reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
}
});
return promise2;
}
// 处理promise2的决议逻辑
resolvePromise(promise2, x, resolve, reject) {
// 防止then方法被多次调用
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
// x为null或x不是对象或函数时,直接用x的值解决promise2
if (x === null || typeof x !== 'object' && typeof x !== 'function') {
return resolve(x);
}
// 解决Promise之间的循环引用问题
let called;
try {
// 判断x是否有then方法,如果有则将x视为Promise
let then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
this.resolvePromise(promise2, y, resolve, reject);
}, r => {
if (called) return;
called = true;
reject(r);
});
} else {
resolve(x);
}
} catch (error) {
// 当then方法调用出错时,用error来解决promise2
if (called) return;
called = true;
reject(error);
}
}
}
module.exports = MyPromise;
```
上面的代码展示了如何从基础开始构建一个简化版的Promise。其核心功能包括:
1. 构造函数中接受一个执行函数,并在内部设置状态、值和失败原因。
2. 成功和失败的回调函数分别绑定到resolve和reject上。
3. then方法用于注册成功或失败的回调函数,它会返回一个新的Promise对象,可以根据前一个Promise的状态决定如何处理。
4. resolvePromise方法用于处理then方法中返回的值,这个值可能是另一个Promise对象,需要特别处理(例如解决Promise的嵌套问题)。
这段代码仅是一个简化版的Promise实现,用于教学目的。真正的Promise规范要复杂得多,包括处理并发、异常捕获和链式调用等多种情况。
在实际应用中,使用JavaScript内置的Promise对象会更为方便和高效,因为它们包含了完整的错误处理机制和优化过的性能表现。但对于学习和深入理解异步编程模型,手写Promise是一个很好的练习项目。
点击了解资源详情
点击了解资源详情
点击了解资源详情
2021-07-16 上传
2021-07-16 上传
2021-07-14 上传
2021-07-14 上传
2021-07-16 上传
2021-07-15 上传
weixin_38599537
- 粉丝: 8
- 资源: 922
最新资源
- dmfont:DM-Font的PyTorch正式实施(ECCV 2020)
- 像素艺术制作者:使用JQuery创建像素艺术的网站
- Graphics:Visual Studio 2019入门项目
- map_viewing_program.rar_GIS编程_C#_
- curso_html5_css3:网站barbararia Alura,当前HTML5和CSS3的完整版本
- matlab心线代码-cpmodel-jap:心肺模型-JAP2020-Karamolegkos,Albanese,Chbat
- FCC-Responsive-Web-Design
- UrFU:实验室工作,项目和其他与研究相关的
- PRS:多程序计算机的仿真模型
- 适用于iOS的Product Hunt徽章-Swift开发
- Azure_devop_IaC-Terraform:使用Terraform创建应用IaC概念的Azure AppService
- sift.rar_matlab例程_matlab_
- Symfony_Voitures:CRUD固定装置和Faker
- Home alarm-开源
- Project_Hybrid_VotingApp
- EMS For Google Calendar-crx插件