深入理解JavaScript状态模式与手动实现Promise

需积分: 9 0 下载量 157 浏览量 更新于2024-12-25 收藏 877B ZIP 举报
资源摘要信息:"js代码-状态模式 手写promise" 状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为。在JavaScript中,Promise是一个非常重要的异步编程模型,它使用状态模式来管理异步操作的三个状态:pending(等待中)、fulfilled(已成功)和rejected(已失败)。 在本资源中,我们将探讨如何通过状态模式手动实现一个简化版的Promise。Promise的设计允许我们注册回调函数来处理异步操作的成功和失败结果,而不需要使用回调地狱(callback hell)或者将错误处理逻辑与业务逻辑耦合在一起。 ### 状态模式的核心概念 - **状态**:对象内部状态的表示,可以理解为一组属性和方法的集合。 - **上下文**:状态模式中被管理的对象,它维护一个状态实例,并把客户端请求委托给当前状态对象。 - **状态管理**:上下文通过状态管理器来切换状态,并且状态管理器负责维护状态对象。 ### Promise的三个状态 Promise有三个状态,每个状态都对应一系列的行为。 1. **Pending(等待中)**:初始状态,既不是成功,也不是失败状态。 2. **Fulfilled(已成功)**:意味着操作成功完成。 3. **Rejected(已失败)**:意味着操作失败。 ### 手写Promise的关键步骤 在手写Promise时,我们需要理解并实现以下关键部分: 1. **Promise构造函数**:接收一个执行器函数,这个函数有两个参数`resolve`和`reject`,分别用来改变Promise的状态为fulfilled或rejected。 2. **then方法**:用来注册成功和失败的回调函数。需要处理异步操作完成后的状态,如果状态是fulfilled,则执行成功回调,如果状态是rejected,则执行失败回调。 3. **resolve和reject函数**:这两个函数分别用来将Promise的状态从pending改变为fulfilled或rejected。 4. **链式调用**:then方法返回的是一个新的Promise实例,这样可以实现多个then方法的链式调用。 ### 示例代码结构 ```javascript // main.js class MyPromise { // Promise的三个状态常量 static PENDING = 'pending'; static FULFILLED = 'fulfilled'; static REJECTED = 'rejected'; // Promise的初始状态 state = MyPromise.PENDING; // 成功值 value = null; // 失败原因 reason = null; // 成功回调函数队列 onFulfilledCallbacks = []; // 失败回调函数队列 onRejectedCallbacks = []; constructor(executor) { // 执行器函数立即执行 try { executor(this.resolve, this.reject); } catch (error) { this.reject(error); } } // 改变状态为fulfilled的方法 resolve = (value) => { if (this.state === MyPromise.PENDING) { this.state = MyPromise.FULFILLED; this.value = value; this.onFulfilledCallbacks.forEach(fn => fn(value)); } } // 改变状态为rejected的方法 reject = (reason) => { if (this.state === MyPromise.PENDING) { this.state = MyPromise.REJECTED; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn(reason)); } } // then方法 then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value; onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }; // 返回一个新Promise return new MyPromise((resolve, reject) => { if (this.state === MyPromise.FULFILLED) { // 异步执行onFulfilled setTimeout(() => { try { const x = onFulfilled(this.value); this.resolvePromise(x, resolve, reject); } catch (error) { reject(error); } }, 0); } else if (this.state === MyPromise.REJECTED) { // 异步执行onRejected setTimeout(() => { try { const x = onRejected(this.reason); this.resolvePromise(x, resolve, reject); } catch (error) { reject(error); } }, 0); } else if (this.state === MyPromise.PENDING) { // 状态未定,先缓存回调函数 this.onFulfilledCallbacks.push((value) => { setTimeout(() => { try { const x = onFulfilled(value); this.resolvePromise(x, resolve, reject); } catch (error) { reject(error); } }, 0); }); this.onRejectedCallbacks.push((reason) => { setTimeout(() => { try { const x = onRejected(reason); this.resolvePromise(x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } }); } // 解析then回调函数返回的值x resolvePromise(x, resolve, reject) { // x为null或非对象,直接resolve if (x === null || typeof x !== 'object' && typeof x !== 'function') { return resolve(x); } // 防止循环引用 let called; try { const then = x.then; if (typeof then === 'function') { then.call( x, y => { if (called) return; called = true; this.resolvePromise(y, resolve, reject); }, r => { if (called) return; called = true; reject(r); } ); } else { resolve(x); } } catch (error) { if (called) return; called = true; reject(error); } } } // README.txt // 该README文件包含了如何使用手写的Promise对象以及如何测试其功能。 // 用户可以通过创建Promise实例来执行异步代码,并通过then方法来处理异步操作的结果。 ``` ### 知识点总结 - 状态模式是一种行为设计模式,它允许对象在内部状态改变时改变其行为。 - JavaScript中的Promise对象使用状态模式来管理异步操作的三种状态:pending(等待中)、fulfilled(已成功)和rejected(已失败)。 - 手写Promise涉及理解Promise的构造函数、resolve和reject方法、then方法的实现以及链式调用的原理。 - Promise的then方法可以接受两个参数,分别对应异步操作成功和失败时的回调函数。 - Promise的链式调用允许我们按照顺序执行多个异步操作,并且每个then方法的回调函数返回的结果可以传递到下一个then方法的回调函数中。 - 在手写Promise时,需要处理异步操作的状态改变,并且考虑到如何处理异步回调函数中的返回值,以及如何实现状态的正确转换。 通过以上内容的学习,开发者可以更好地理解JavaScript中Promise的工作机制,并且能够手动实现一个符合Promises/A+规范的Promise对象,这对于深入掌握异步编程和JavaScript语言特性非常有帮助。