mypromise: 深入理解JavaScript中的Promise简易实现

需积分: 11 0 下载量 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不仅可以增进对异步编程的理解,还能够提升解决问题和处理复杂情况的能力。