从零实现Promise:深度解析all与race核心机制
2025.09.19 12:47浏览量:0简介:本文通过手写实现Promise类及其all、race方法,深入解析异步编程核心机制,包含状态管理、链式调用、并发控制等关键点的代码实现与原理剖析。
深度解析Promise核心机制与实现
一、Promise基础实现原理
1.1 状态机设计
Promise的核心是状态管理系统,包含三种状态:
- Pending(初始态)
- Fulfilled(成功态)
- Rejected(失败态)
状态转换规则:
- 只能从Pending转为Fulfilled或Rejected
- 状态一旦改变不可逆
class MyPromise {
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(fn => fn());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
}
1.2 链式调用实现
then方法的核心是返回新Promise实现链式调用:
then(onFulfilled, onRejected) {
// 参数默认值处理
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.state === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
} else if (this.state === 'pending') {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
});
return promise2;
}
1.3 异步执行机制
使用setTimeout将回调推入宏任务队列,保证:
- 同步代码优先执行
- 回调按注册顺序执行
- 符合Promise/A+规范的执行时序
二、Promise.all实现解析
2.1 核心功能
接收Promise数组,返回新Promise:
- 所有输入Promise成功时,返回结果数组
- 任意Promise失败时,立即返回失败原因
2.2 实现代码
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = [];
let count = 0;
if (promises.length === 0) {
resolve(results);
return;
}
promises.forEach((promise, index) => {
// 处理非Promise值
MyPromise.resolve(promise).then(
value => {
results[index] = value;
count++;
if (count === promises.length) {
resolve(results);
}
},
reason => {
reject(reason);
}
);
});
});
}
2.3 关键点解析
- 结果数组顺序保持与输入一致
- 使用MyPromise.resolve处理非Promise值
- 计数器机制确保所有Promise完成
- 遇到第一个错误立即终止
三、Promise.race实现解析
3.1 核心功能
接收Promise数组,返回新Promise:
- 第一个完成(成功/失败)的Promise决定结果
- 后续Promise结果被忽略
3.2 实现代码
static race(promises) {
return new MyPromise((resolve, reject) => {
if (promises.length === 0) {
return; // 空数组不改变状态
}
promises.forEach(promise => {
MyPromise.resolve(promise).then(
value => {
resolve(value);
},
reason => {
reject(reason);
}
);
});
});
}
3.3 关键点解析
- 立即响应第一个完成的结果
- 使用MyPromise.resolve确保值处理
- 空数组处理与all方法保持一致
- 竞速机制实现
四、完整实现与测试
4.1 完整代码
class MyPromise {
// ...前文所有代码...
static resolve(value) {
if (value instanceof MyPromise) {
return value;
}
return new MyPromise(resolve => resolve(value));
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(callback) {
return this.then(
value => MyPromise.resolve(callback()).then(() => value),
reason => MyPromise.resolve(callback()).then(() => { throw reason })
);
}
}
4.2 测试用例
// 基础功能测试
const p1 = new MyPromise((resolve) => {
setTimeout(() => resolve('成功'), 1000);
});
p1.then(console.log); // 1秒后输出"成功"
// all方法测试
const p2 = Promise.resolve(1);
const p3 = new MyPromise(resolve => resolve(2));
const p4 = 3;
MyPromise.all([p2, p3, p4]).then(console.log); // 输出[1, 2, 3]
// race方法测试
const p5 = new MyPromise(resolve => setTimeout(() => resolve('慢'), 200));
const p6 = new MyPromise(resolve => setTimeout(() => resolve('快'), 100));
MyPromise.race([p5, p6]).then(console.log); // 100ms后输出"快"
五、实际应用场景
5.1 并行请求优化
// 同时发起多个API请求
const userInfo = fetch('/api/user');
const orders = fetch('/api/orders');
const notifications = fetch('/api/notifications');
MyPromise.all([userInfo, orders, notifications])
.then(([user, orders, notifications]) => {
// 统一处理所有数据
});
5.2 超时控制实现
function withTimeout(promise, timeout) {
const timeoutPromise = new MyPromise((_, reject) => {
setTimeout(() => reject(new Error('Timeout')), timeout);
});
return MyPromise.race([promise, timeoutPromise]);
}
// 使用示例
withTimeout(fetch('/api/data'), 5000)
.then(console.log)
.catch(err => console.error(err.message));
5.3 资源加载控制
// 竞速加载最佳资源
function loadBestResource(resources) {
return MyPromise.race(
resources.map(url => {
const start = performance.now();
return fetch(url).then(res => {
const duration = performance.now() - start;
console.log(`${url} loaded in ${duration}ms`);
return res;
});
})
);
}
六、性能优化建议
- 批量处理优化:对于大量Promise的all操作,考虑分批处理
- 错误边界处理:在all方法中添加最大错误重试机制
- 内存管理:长时间运行的race操作应提供取消机制
- 并行度控制:实现类似Promise.map的并发控制方法
七、常见问题解决方案
7.1 循环引用问题
// 错误示例
const p = new MyPromise(resolve => resolve());
p.then(() => p); // 导致堆栈溢出
// 解决方案:添加循环检测
then(onFulfilled, onRejected) {
// ...前文代码...
const promise2 = new MyPromise((resolve, reject) => {
// 添加循环检测
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected'));
}
// ...剩余代码...
});
}
7.2 内存泄漏处理
// 在all/race方法中添加清理机制
static all(promises) {
let shouldResolve = true;
return new MyPromise((resolve, reject) => {
// ...前文代码...
const cleanup = () => shouldResolve = false;
// 在适当位置调用cleanup
});
}
八、进阶实现方向
- Promise.any:实现首个成功的Promise返回
- Promise.allSettled:返回所有Promise的结果状态
- Promise.try:统一同步/异步错误处理
- 取消机制:实现可取消的Promise
通过本文的完整实现,开发者可以深入理解Promise的核心机制,掌握all和race方法的实现原理,并能够在实际项目中灵活运用这些技术。完整代码已在GitHub开源,欢迎贡献改进建议。
发表评论
登录后可评论,请前往 登录 或 注册