logo

从零实现Promise:深度解析all与race核心机制

作者:问题终结者2025.09.19 12:47浏览量:0

简介:本文通过手写实现Promise类及其all、race方法,深入解析异步编程核心机制,包含状态管理、链式调用、并发控制等关键点的代码实现与原理剖析。

深度解析Promise核心机制与实现

一、Promise基础实现原理

1.1 状态机设计

Promise的核心是状态管理系统,包含三种状态:

  • Pending(初始态)
  • Fulfilled(成功态)
  • Rejected(失败态)

状态转换规则:

  1. 只能从Pending转为Fulfilled或Rejected
  2. 状态一旦改变不可逆
  1. class MyPromise {
  2. constructor(executor) {
  3. this.state = 'pending'; // 初始状态
  4. this.value = undefined; // 成功值
  5. this.reason = undefined; // 失败原因
  6. this.onFulfilledCallbacks = []; // 成功回调队列
  7. this.onRejectedCallbacks = []; // 失败回调队列
  8. const resolve = (value) => {
  9. if (this.state === 'pending') {
  10. this.state = 'fulfilled';
  11. this.value = value;
  12. this.onFulfilledCallbacks.forEach(fn => fn());
  13. }
  14. };
  15. const reject = (reason) => {
  16. if (this.state === 'pending') {
  17. this.state = 'rejected';
  18. this.reason = reason;
  19. this.onRejectedCallbacks.forEach(fn => fn());
  20. }
  21. };
  22. try {
  23. executor(resolve, reject);
  24. } catch (err) {
  25. reject(err);
  26. }
  27. }
  28. }

1.2 链式调用实现

then方法的核心是返回新Promise实现链式调用:

  1. then(onFulfilled, onRejected) {
  2. // 参数默认值处理
  3. onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
  4. onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
  5. const promise2 = new MyPromise((resolve, reject) => {
  6. if (this.state === 'fulfilled') {
  7. setTimeout(() => {
  8. try {
  9. const x = onFulfilled(this.value);
  10. resolvePromise(promise2, x, resolve, reject);
  11. } catch (e) {
  12. reject(e);
  13. }
  14. }, 0);
  15. } else if (this.state === 'rejected') {
  16. setTimeout(() => {
  17. try {
  18. const x = onRejected(this.reason);
  19. resolvePromise(promise2, x, resolve, reject);
  20. } catch (e) {
  21. reject(e);
  22. }
  23. }, 0);
  24. } else if (this.state === 'pending') {
  25. this.onFulfilledCallbacks.push(() => {
  26. setTimeout(() => {
  27. try {
  28. const x = onFulfilled(this.value);
  29. resolvePromise(promise2, x, resolve, reject);
  30. } catch (e) {
  31. reject(e);
  32. }
  33. }, 0);
  34. });
  35. this.onRejectedCallbacks.push(() => {
  36. setTimeout(() => {
  37. try {
  38. const x = onRejected(this.reason);
  39. resolvePromise(promise2, x, resolve, reject);
  40. } catch (e) {
  41. reject(e);
  42. }
  43. }, 0);
  44. });
  45. }
  46. });
  47. return promise2;
  48. }

1.3 异步执行机制

使用setTimeout将回调推入宏任务队列,保证:

  1. 同步代码优先执行
  2. 回调按注册顺序执行
  3. 符合Promise/A+规范的执行时序

二、Promise.all实现解析

2.1 核心功能

接收Promise数组,返回新Promise:

  • 所有输入Promise成功时,返回结果数组
  • 任意Promise失败时,立即返回失败原因

2.2 实现代码

  1. static all(promises) {
  2. return new MyPromise((resolve, reject) => {
  3. const results = [];
  4. let count = 0;
  5. if (promises.length === 0) {
  6. resolve(results);
  7. return;
  8. }
  9. promises.forEach((promise, index) => {
  10. // 处理非Promise值
  11. MyPromise.resolve(promise).then(
  12. value => {
  13. results[index] = value;
  14. count++;
  15. if (count === promises.length) {
  16. resolve(results);
  17. }
  18. },
  19. reason => {
  20. reject(reason);
  21. }
  22. );
  23. });
  24. });
  25. }

2.3 关键点解析

  1. 结果数组顺序保持与输入一致
  2. 使用MyPromise.resolve处理非Promise值
  3. 计数器机制确保所有Promise完成
  4. 遇到第一个错误立即终止

三、Promise.race实现解析

3.1 核心功能

接收Promise数组,返回新Promise:

  • 第一个完成(成功/失败)的Promise决定结果
  • 后续Promise结果被忽略

3.2 实现代码

  1. static race(promises) {
  2. return new MyPromise((resolve, reject) => {
  3. if (promises.length === 0) {
  4. return; // 空数组不改变状态
  5. }
  6. promises.forEach(promise => {
  7. MyPromise.resolve(promise).then(
  8. value => {
  9. resolve(value);
  10. },
  11. reason => {
  12. reject(reason);
  13. }
  14. );
  15. });
  16. });
  17. }

3.3 关键点解析

  1. 立即响应第一个完成的结果
  2. 使用MyPromise.resolve确保值处理
  3. 空数组处理与all方法保持一致
  4. 竞速机制实现

四、完整实现与测试

4.1 完整代码

  1. class MyPromise {
  2. // ...前文所有代码...
  3. static resolve(value) {
  4. if (value instanceof MyPromise) {
  5. return value;
  6. }
  7. return new MyPromise(resolve => resolve(value));
  8. }
  9. catch(onRejected) {
  10. return this.then(null, onRejected);
  11. }
  12. finally(callback) {
  13. return this.then(
  14. value => MyPromise.resolve(callback()).then(() => value),
  15. reason => MyPromise.resolve(callback()).then(() => { throw reason })
  16. );
  17. }
  18. }

4.2 测试用例

  1. // 基础功能测试
  2. const p1 = new MyPromise((resolve) => {
  3. setTimeout(() => resolve('成功'), 1000);
  4. });
  5. p1.then(console.log); // 1秒后输出"成功"
  6. // all方法测试
  7. const p2 = Promise.resolve(1);
  8. const p3 = new MyPromise(resolve => resolve(2));
  9. const p4 = 3;
  10. MyPromise.all([p2, p3, p4]).then(console.log); // 输出[1, 2, 3]
  11. // race方法测试
  12. const p5 = new MyPromise(resolve => setTimeout(() => resolve('慢'), 200));
  13. const p6 = new MyPromise(resolve => setTimeout(() => resolve('快'), 100));
  14. MyPromise.race([p5, p6]).then(console.log); // 100ms后输出"快"

五、实际应用场景

5.1 并行请求优化

  1. // 同时发起多个API请求
  2. const userInfo = fetch('/api/user');
  3. const orders = fetch('/api/orders');
  4. const notifications = fetch('/api/notifications');
  5. MyPromise.all([userInfo, orders, notifications])
  6. .then(([user, orders, notifications]) => {
  7. // 统一处理所有数据
  8. });

5.2 超时控制实现

  1. function withTimeout(promise, timeout) {
  2. const timeoutPromise = new MyPromise((_, reject) => {
  3. setTimeout(() => reject(new Error('Timeout')), timeout);
  4. });
  5. return MyPromise.race([promise, timeoutPromise]);
  6. }
  7. // 使用示例
  8. withTimeout(fetch('/api/data'), 5000)
  9. .then(console.log)
  10. .catch(err => console.error(err.message));

5.3 资源加载控制

  1. // 竞速加载最佳资源
  2. function loadBestResource(resources) {
  3. return MyPromise.race(
  4. resources.map(url => {
  5. const start = performance.now();
  6. return fetch(url).then(res => {
  7. const duration = performance.now() - start;
  8. console.log(`${url} loaded in ${duration}ms`);
  9. return res;
  10. });
  11. })
  12. );
  13. }

六、性能优化建议

  1. 批量处理优化:对于大量Promise的all操作,考虑分批处理
  2. 错误边界处理:在all方法中添加最大错误重试机制
  3. 内存管理:长时间运行的race操作应提供取消机制
  4. 并行度控制:实现类似Promise.map的并发控制方法

七、常见问题解决方案

7.1 循环引用问题

  1. // 错误示例
  2. const p = new MyPromise(resolve => resolve());
  3. p.then(() => p); // 导致堆栈溢出
  4. // 解决方案:添加循环检测
  5. then(onFulfilled, onRejected) {
  6. // ...前文代码...
  7. const promise2 = new MyPromise((resolve, reject) => {
  8. // 添加循环检测
  9. if (promise2 === x) {
  10. return reject(new TypeError('Chaining cycle detected'));
  11. }
  12. // ...剩余代码...
  13. });
  14. }

7.2 内存泄漏处理

  1. // 在all/race方法中添加清理机制
  2. static all(promises) {
  3. let shouldResolve = true;
  4. return new MyPromise((resolve, reject) => {
  5. // ...前文代码...
  6. const cleanup = () => shouldResolve = false;
  7. // 在适当位置调用cleanup
  8. });
  9. }

八、进阶实现方向

  1. Promise.any:实现首个成功的Promise返回
  2. Promise.allSettled:返回所有Promise的结果状态
  3. Promise.try:统一同步/异步错误处理
  4. 取消机制:实现可取消的Promise

通过本文的完整实现,开发者可以深入理解Promise的核心机制,掌握all和race方法的实现原理,并能够在实际项目中灵活运用这些技术。完整代码已在GitHub开源,欢迎贡献改进建议。

相关文章推荐

发表评论