手写实现 promise
手动实现Promise类
Promise 是 JavaScript 中用于处理异步操作的对象,我们可以手写实现一个符合 Promise A+ 规范的 Promise。
首先需要理解 Promise 的基本结构和功能。Promise 对象包含三种状态:pending
(等待中)、fulfilled
(已成功)和 rejected
(已失败)。当 Promise 转换到 fulfilled 或 rejected 状态时,会把结果值或错误原因传递给 then 方法注册的回调函数。
以下是一个简单的 Promise 实现:
class CustomPromise {constructor(executor) {this.state = 'pending';this.value = undefined;this.reason = undefined;this.onFulfilledCallbacks = [];this.onRejectedCallbacks = [];const resolve = (value) => {if (this.state === 'pending') {this.state = 'fulfilled';this.value = value;this.onFulfilledCallbacks.forEach((callback) => callback(value));}};const reject = (reason) => {if (this.state === 'pending') {this.state = 'rejected';this.reason = reason;this.onRejectedCallbacks.forEach((callback) => callback(reason));}};try {executor(resolve, reject);} catch (error) {reject(error);}}then(onFulfilled, onRejected) {return new CustomPromise((resolve, reject) => {if (this.state === 'fulfilled') {try {const value =typeof onFulfilled === 'function' ? onFulfilled(this.value) : this.value;resolve(value);} catch (error) {reject(error);}} else if (this.state === 'rejected') {try {const reason =typeof onRejected === 'function' ? onRejected(this.reason) : this.reason;reject(reason);} catch (error) {reject(error);}} else {this.onFulfilledCallbacks.push((value) => {try {const returnValue =typeof onFulfilled === 'function' ? onFulfilled(value) : value;resolve(returnValue);} catch (error) {reject(error);}});this.onRejectedCallbacks.push((reason) => {try {const returnValue =typeof onRejected === 'function' ? onRejected(reason) : reason;reject(returnValue);} catch (error) {reject(error);}});}});}catch(onRejected) {return this.then(null, onRejected);}finally(onFinally) {return this.then((value) =>CustomPromise.resolve(onFinally()).then(() => {return value;}),(reason) =>CustomPromise.resolve(onFinally()).then(() => {throw reason;}));}static resolve(value) {return new CustomPromise((resolve) => resolve(value));}static reject(reason) {return new CustomPromise((resolve, reject) => reject(reason));}static all(promises) {return new CustomPromise((resolve, reject) => {const results = Array(promises.length);let count = 0;promises.forEach((promise, index) => {CustomPromise.resolve(promise).then((value) => {results[index] = value;count++;if (count === promises.length) {resolve(results);}},(reason) => {reject(reason);});});});}static race(promises) {return new CustomPromise((resolve, reject) => {promises.forEach((promise) => {CustomPromise.resolve(promise).then(resolve, reject);});});}
}
这个实现中用到了构造函数、then 方法、catch 方法、finally 方法和静态方法 resolve、reject、all 和 race。在构造函数中,通过传入一个 executor 函数,创建了一个新的 CustomPromise 对象,并且在 executor 函数中调用 resolve 或 reject 来改变 CustomPromise 的状态;在 then 方法中,通过不同状态下返回值的处理,实现了链式调用。
需要注意的是,在实现中使用了数组来保存每个回调函数,因为 Promise 可能会存在多个 then 方法,当状态改变时需要执行所有的回调函数,而保存回调函数的数组也是实现 Promise 链式调用的关键。
此外,这个实现还加入了 catch 和 finally 方法,用于捕获 Promise 的错误和添加无论 Promise 状态如何都会执行的逻辑。
使用CustomPromise
首先可以创建一个新的 CustomPromise 对象,传入一个 executor 函数。executor 函数接受两个参数:resolve 和 reject,分别代表成功和失败的回调函数。当异步操作成功时,调用 resolve 方法并传入成功结果值;当异步操作失败时,调用 reject 方法并传入错误原因。
然后就可以在 CustomPromise 实例上调用 then 方法来注册处理 Promise 成功和失败的回调函数。then 方法接受两个参数:onFulfilled 和 onRejected,分别代表成功和失败的回调函数。这些回调函数会在 Promise 转换到 fulfilled 或 rejected 状态时被调用,并且会把结果值或错误原因传递给它们。
除了 then 方法,CustomPromise 类还提供了 catch 方法用于捕获 Promise 的错误,以及 finally 方法用于添加无论 Promise 状态如何都会执行的逻辑。
以下是使用 CustomPromise 处理异步操作的示例代码:
const customPromise = new CustomPromise((resolve, reject) => {// 异步操作setTimeout(() => {const randomNum = Math.random();if (randomNum > 0.5) {resolve('success');} else {reject('failed');}}, 1000);
});customPromise.then((value) => {console.log(value);},(reason) => {console.log(reason);}
);customPromise.catch((error) => {console.log(error);
});customPromise.finally(() => {console.log('finally');
});
在这个示例中,我们创建了一个 CustomPromise 对象来模拟异步操作。在 executor 函数中使用 setTimeout 模拟异步操作,并根据随机生成的数值来改变 CustomPromise 的状态。然后调用 then 方法、catch 方法和 finally 方法来注册处理 Promise 成功和失败的回调函数以及添加执行无论 Promise 状态如何都会执行的逻辑。