引言
在现代 JavaScript 开发中,Promise
是异步操作的核心工具。无论是简单的回调替代,还是复杂的异步任务管理,Promise
都提供了一种简洁、高效的方式。然而,理解其内部实现和优化点不仅有助于掌握异步编程的本质,也能提升代码的性能与可维护性。
本文将探索如何实现一个高效、功能完善的 Promise
,并剖析其中的核心机制与优化细节。
Promise 的核心机制
Promise 的底层基于状态机思想,其状态具有以下特性:
-
三种状态:
pending
(初始状态):表示异步操作尚未完成。fulfilled
(已完成):表示异步操作成功完成。rejected
(已拒绝):表示异步操作失败。
-
不可逆性:
- 状态只能从
pending
转为fulfilled
或rejected
,一旦变更,状态将无法再次改变。
- 状态只能从
-
异步回调触发:
- 注册的回调函数(通过
then
或catch
)必须在状态变更后异步执行,符合 JavaScript 事件循环的微任务调度规则。
- 注册的回调函数(通过
优化后的 Promise 实现
以下是优化版 Promise
的完整实现,涵盖了基本功能、链式调用、静态方法等,同时对性能和易用性进行了提升。
javascript
class OptimizedPromise {
constructor(executor) {
this.state = "pending"; // 初始状态
this.value = undefined; // 成功的值
this.reason = undefined; // 失败的原因
this.callbacks = []; // 存储回调函数
const resolve = (value) => {
if (this.state === "pending") {
this.state = "fulfilled";
this.value = value;
queueMicrotask(() => {
this.callbacks.forEach(({ onFulfilled }) => {
if (onFulfilled) onFulfilled(this.value);
});
});
}
};
const reject = (reason) => {
if (this.state === "pending") {
this.state = "rejected";
this.reason = reason;
queueMicrotask(() => {
this.callbacks.forEach(({ onRejected }) => {
if (onRejected) onRejected(this.reason);
});
});
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
return new OptimizedPromise((resolve, reject) => {
const handleCallback = () => {
try {
if (this.state === "fulfilled") {
if (onFulfilled) {
const result = onFulfilled(this.value);
resolve(result instanceof OptimizedPromise ? result : result);
} else {
resolve(this.value);
}
} else if (this.state === "rejected") {
if (onRejected) {
const result = onRejected(this.reason);
resolve(result instanceof OptimizedPromise ? result : result);
} else {
reject(this.reason);
}
}
} catch (error) {
reject(error);
}
};
if (this.state === "pending") {
this.callbacks.push({
onFulfilled: handleCallback,
onRejected: handleCallback,
});
} else {
queueMicrotask(handleCallback);
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(callback) {
return this.then(
(value) => {
callback();
return value;
},
(reason) => {
callback();
throw reason;
}
);
}
static resolve(value) {
return new OptimizedPromise((resolve) => resolve(value));
}
static reject(reason) {
return new OptimizedPromise((_, reject) => reject(reason));
}
static all(promises) {
return new OptimizedPromise((resolve, reject) => {
const results = [];
let completed = 0;
promises.forEach((promise, index) => {
OptimizedPromise.resolve(promise)
.then((value) => {
results[index] = value;
completed++;
if (completed === promises.length) resolve(results);
})
.catch(reject);
});
});
}
static race(promises) {
return new OptimizedPromise((resolve, reject) => {
promises.forEach((promise) => {
OptimizedPromise.resolve(promise).then(resolve).catch(reject);
});
});
}
}
实现细节与优化点
1. 状态管理
通过 state
来记录当前的状态,并在 resolve
和 reject
中处理状态流转。不可逆状态设计确保了操作的幂等性。
2. 异步调度
使用 queueMicrotask
实现微任务调度,确保回调函数异步执行,比传统的 setTimeout
更高效且符合 ECMAScript 规范。
3. 链式调用
then
方法中处理返回值类型,支持普通值和嵌套 Promise
:
- 如果返回普通值,直接
resolve
。 - 如果返回另一个
Promise
,则等待其完成再继续。
4. 静态方法
resolve
和reject
:快速创建已完成或已拒绝的Promise
。all
:并发处理多个Promise
,返回所有完成结果。race
:返回第一个完成的Promise
,无论成功还是失败。
完整测试用例
测试基础功能
javascript
const p1 = OptimizedPromise.resolve(1);
p1.then((value) => console.log("Resolved:", value)); // 输出 Resolved: 1
const p2 = new OptimizedPromise((resolve, reject) => {
setTimeout(() => resolve(2), 100);
});
p2.then((value) => console.log("Async Resolved:", value)); // 输出 Async Resolved: 2
测试链式调用
javascript
p1.then((value) => value * 2)
.then((value) => new OptimizedPromise((resolve) => resolve(value + 3)))
.then((value) => console.log("Chained Value:", value)); // 输出 Chained Value: 5
测试 all
和 race
javascript
const p3 = OptimizedPromise.reject("Error!");
OptimizedPromise.all([p1, p2]).then((values) => console.log("All Resolved:", values)); // 输出 All Resolved: [1, 2]
OptimizedPromise.race([p2, p3]).catch((reason) => console.log("Race Rejected:", reason)); // 输出 Race Rejected: Error!
测试 finally
javascript
p2.finally(() => console.log("Cleaning up...")).then((value) => console.log("Value:", value));
// 输出:
// Cleaning up...
// Value: 2
总结
这份优化后的 Promise
实现从状态管理、异步调度、链式调用到静态方法都做到了高效与规范。通过支持 finally
和链式嵌套,解决了真实开发中可能遇到的复杂场景。
核心亮点:
- 微任务调度确保异步回调顺序。
- 支持所有常见静态方法(
resolve
、reject
、all
、race
)。 - 完整覆盖异常处理和链式调用。
通过深入理解其实现细节,你不仅可以更好地掌握 Promise
的原理,还能在实际开发中写出更高效、健壮的异步代码。