如何在Node.js中实现Promise?求提供具体实现示例
嘿,这个问题问到点子上了!要手动实现Promise,得先吃透它的核心规则:状态只能从pending转为fulfilled或rejected,一旦改变就再也不能变;then方法可以注册成功/失败的回调,还支持链式调用;异步操作的回调要能被正确触发。
我给你写一个符合Promise A+规范的简化版实现,每一步都加上注释,方便你理解:
手动实现Promise(简化版)
class MyPromise { // 定义三种核心状态 static PENDING = 'pending'; static FULFILLED = 'fulfilled'; static REJECTED = 'rejected'; constructor(executor) { // 初始化状态为pending this.status = MyPromise.PENDING; // 存储成功时的返回值 this.value = null; // 存储失败时的错误原因 this.reason = null; // 缓存异步场景下的成功回调(状态未改变时注册) this.onFulfilledCallbacks = []; // 缓存异步场景下的失败回调 this.onRejectedCallbacks = []; // resolve函数:将状态转为fulfilled并触发回调 const resolve = (value) => { // 只有pending状态能被修改 if (this.status === MyPromise.PENDING) { this.status = MyPromise.FULFILLED; this.value = value; // 批量触发所有缓存的成功回调 this.onFulfilledCallbacks.forEach(callback => callback()); } }; // reject函数:将状态转为rejected并触发回调 const reject = (reason) => { if (this.status === MyPromise.PENDING) { this.status = MyPromise.REJECTED; this.reason = reason; // 批量触发所有缓存的失败回调 this.onRejectedCallbacks.forEach(callback => callback()); } }; // 立即执行传入的executor函数,捕获同步错误 try { executor(resolve, reject); } catch (error) { reject(error); } } // then方法:注册回调并返回新Promise实现链式调用 then(onFulfilled, onRejected) { // 处理参数默认值:没传回调时做透传处理 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value; onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; }; // 返回新Promise,保证链式调用的独立性 const promise2 = new MyPromise((resolve, reject) => { // 状态已为fulfilled时,直接执行成功回调 if (this.status === MyPromise.FULFILLED) { // 用setTimeout模拟异步执行,符合Promise规范的微任务要求 setTimeout(() => { try { const x = onFulfilled(this.value); // 处理回调返回值:如果是Promise则等待其完成,否则直接resolve this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } // 状态已为rejected时,直接执行失败回调 if (this.status === MyPromise.REJECTED) { setTimeout(() => { try { const x = onRejected(this.reason); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } // 状态还是pending时,将回调缓存起来 if (this.status === MyPromise.PENDING) { this.onFulfilledCallbacks.push(() => { setTimeout(() => { try { const x = onFulfilled(this.value); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const x = onRejected(this.reason); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } }); return promise2; } // 处理then回调返回值的统一逻辑,符合Promise A+规范 resolvePromise(promise2, x, resolve, reject) { // 避免循环引用 if (promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise')); } // 如果返回值是Promise实例,等待其状态变更 if (x instanceof MyPromise) { x.then(resolve, reject); } else { // 普通值直接resolve resolve(x); } } // catch方法:语法糖,等价于then(null, onRejected) catch(onRejected) { return this.then(null, onRejected); } }
测试我们的Promise实现
用一个模拟异步请求的场景来验证功能:
// 模拟异步接口请求 function fetchMockData() { return new MyPromise((resolve, reject) => { setTimeout(() => { // 随机模拟成功/失败 const isSuccess = Math.random() > 0.5; if (isSuccess) { resolve('模拟请求成功:拿到用户数据'); } else { reject('模拟请求失败:服务器超时'); } }, 1000); }); } // 使用自定义Promise fetchMockData() .then(data => { console.log(data); return `加工后的数据:${data}`; }) .then(processedData => { console.log(processedData); }) .catch(error => { console.error('捕获到错误:', error); });
这个实现覆盖了Promise的核心特性:状态不可逆、异步回调触发、链式调用、错误捕获。标准Promise还有更多细节(比如all/race等静态方法、thenable对象处理),但这个简化版足够帮你理解底层逻辑啦~
内容的提问来源于stack exchange,提问作者Chandrashekhar Patidar
相关产品推荐
相关产品推荐

