CodeL
以前端为翼,以 AI 为脑,向全栈而行
2026-03-31

Promise 完全指南

Promise 完全指南:从入门到手写实现 一篇文章彻底搞懂 Promise:基础方法、静态方法、手写实现,附完整代码示例 一、核心概念 1.1 什么是 Promise?(大白话解释) Promise 就是一个"承诺"—...

Promise 完全指南:从入门到手写实现 #

一篇文章彻底搞懂 Promise:基础方法、静态方法、手写实现,附完整代码示例


一、核心概念 #

1.1 什么是 Promise?(大白话解释) #

Promise 就是一个"承诺"——表示一个未来才会知道结果的操作。

打个比方:你去餐厅点餐,服务员给你一个"排队号牌",这就是 Promise。你不知道餐什么时候做好,但你可以:

  • 等餐做好了(成功 resolve)→ 服务员叫号取餐
  • 等餐做失败了(失败 reject)→ 服务员告诉你"不好意思,食材没了"

传统回调 vs Promise 对比:

// 传统回调写法 —— 套娃地狱(Callback Hell)
getUserInfo(userId, function(user) {
  getUserOrders(user.id, function(orders) {
    getOrderDetails(orders[0].id, function(details) {
      console.log(details);
    });
  });
});
 
// Promise 写法 —— 链式调用,清晰优雅
getUserInfo(userId)
  .then(user => getUserOrders(user.id))
  .then(orders => getOrderDetails(orders[0].id))
  .then(details => console.log(details))
  .catch(err => console.error(err));

1.2 为什么需要 Promise? #

Promise 解决了三个核心问题:

问题 传统回调的痛点 Promise 的解决方案
回调地狱 嵌套层层叠叠,难以维护 链式调用 .then(),扁平化
错误处理 每个 callback 都要单独处理 error 统一用 .catch() 捕获
状态管理 无法知道异步操作进行到哪一步 三种状态:pending、fulfilled、rejected

1.3 Promise 的三种状态 #

// Promise 状态图
//
//   pending(进行中)──────┬──→ fulfilled(已成功)
//                          │
//                          └──→ rejected(已失败)
//
// 特点:
// 1. 状态只能改变一次,不能逆转
// 2. pending → fulfilled 或 pending → rejected
// 3. 一旦改变,就固定了(immutable)
状态 含义 能否改变
pending 进行中,还没结果 可以变为 fulfilled 或 rejected
fulfilled 已成功,有 resolve 值 不可再变
rejected 已失败,有 reject 原因 不可再变

二、基础方法详解 #

2.1 Promise 的创建 #

// 创建 Promise
const promise = new Promise((resolve, reject) => {
  // resolve: 成功时调用,把结果传出去
  // reject:  失败时调用,把错误原因传出去
  
  // 模拟异步操作
  setTimeout(() => {
    const success = true;
    
    if (success) {
      resolve('操作成功!');  // 状态变为 fulfilled
    } else {
      reject('操作失败!');   // 状态变为 rejected
    }
  }, 1000);
});

2.2 then() —— 处理成功结果 #

then() 是 Promise 最核心的方法,用于处理 resolve 的结果。

// then 的完整签名
promise.then(
  onFulfilled,  // 成功回调,接收 resolve 的值
  onRejected    // 失败回调(可选),接收 reject 的原因
);
 
// 示例:基本用法
const p1 = Promise.resolve('成功数据');
 
p1.then(value => {
  console.log('收到:', value);  // 输出: 收到: 成功数据
  return '处理后的数据';         // 返回值会传给下一个 then
})
.then(value => {
  console.log('第二次收到:', value);  // 输出: 第二次收到: 处理后的数据
});
 
// 示例:then 返回新 Promise(链式调用的关键)
const p2 = new Promise(resolve => resolve(10));
 
p2.then(value => {
  console.log('第一次:', value);  // 10
  return value * 2;               // 返回普通值
})
.then(value => {
  console.log('第二次:', value);  // 20
  return new Promise(resolve => resolve(value + 5));  // 返回 Promise
})
.then(value => {
  console.log('第三次:', value);  // 25
});

then 的关键规则:

返回值类型 下一个 then 收到的值
普通值(数字、字符串、对象) 直接收到该值
新的 Promise 等这个 Promise resolve 后才收到
没有 return(undefined) 收到 undefined
throw 抛出错误 跳到最近的 catch

2.3 catch() —— 统一错误处理 #

catch().then(null, onRejected) 的简写,专门用于捕获错误。

// catch 基本用法
const pError = new Promise((resolve, reject) => {
  reject('出错了!');
});
 
pError
  .then(value => console.log('成功:', value))  // 不会执行
  .catch(error => console.log('失败:', error)); // 输出: 失败: 出错了!
 
// catch 捕获链式调用中的所有错误
getUserInfo(userId)
  .then(user => getUserOrders(user.id))   // 可能出错
  .then(orders => getOrderDetails(orders[0].id))  // 可能出错
  .catch(err => console.error('某一步出错了:', err));  // 统一捕获
 
// catch 后还能继续 then(错误"恢复")
Promise.reject('失败了')
  .catch(err => {
    console.log('捕获到:', err);
    return '恢复后的值';  // catch 返回值可以继续传递
  })
  .then(value => {
    console.log('继续执行:', value);  // 输出: 继续执行: 恢复后的值
  });

2.4 finally() —— 无论成功失败都执行 #

finally() 不关心结果,只关心"结束了"这个事实。常用于清理工作。

// finally 基本用法
const p = new Promise((resolve, reject) => {
  setTimeout(() => resolve('数据'), 1000);
});
 
p
  .then(value => console.log('成功:', value))
  .catch(error => console.log('失败:', error))
  .finally(() => {
    console.log('无论成功失败,我都会执行!');
    // 常用于:关闭 loading、清理资源、记录日志
  });
 
// 实际场景:关闭 loading
function fetchWithLoading(url) {
  showLoading();  // 显示 loading
  
  return fetch(url)
    .then(res => res.json())
    .catch(err => {
      showError(err);
      throw err;  // 继续抛出,让外部也能捕获
    })
    .finally(() => {
      hideLoading();  // 无论成功失败,都关闭 loading
    });
}

finally 的特点:

  • 不接收任何参数(不知道是成功还是失败)
  • 返回值会被忽略(不影响后续链)
  • 主要是"清理工作"的场景

三、静态方法详解 #

Promise 类提供了多个静态方法,用于批量处理 Promise。

3.1 Promise.all() —— 全部成功才算成功 #

等待所有 Promise 都成功,返回所有结果的数组。有一个失败就整体失败。

// Promise.all 基本用法
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);
 
Promise.all([p1, p2, p3])
  .then(values => {
    console.log(values);  // [1, 2, 3]
  })
  .catch(error => {
    console.log('有一个失败了:', error);
  });
 
// 实际场景:并行请求多个接口
function fetchAllData() {
  const userPromise = fetch('/api/user').then(r => r.json());
  const orderPromise = fetch('/api/orders').then(r => r.json());
  const productPromise = fetch('/api/products').then(r => r.json());
  
  return Promise.all([userPromise, orderPromise, productPromise])
    .then(([user, orders, products]) => {
      return { user, orders, products };  // 三个数据都有了
    });
}
 
// 失败场景:一个失败,整体失败
Promise.all([
  Promise.resolve('成功1'),
  Promise.reject('失败2'),
  Promise.resolve('成功3')
])
.catch(error => {
  console.log('整体失败:', error);  // 输出: 整体失败: 失败2
  // 注意:成功1 和 成功3 的结果丢失了!
});

Promise.all 特点总结:

情况 结果
全部成功 返回所有结果的数组 [v1, v2, v3]
有一个失败 立即 reject,返回第一个失败的原因
顺序 结果顺序与传入顺序一致(不管谁先完成)

3.2 Promise.race() —— 第一个完成就返回 #

返回第一个完成(无论成功失败)的 Promise 结果。

// Promise.race 基本用法
const p1 = new Promise(resolve => setTimeout(() => resolve('慢'), 300));
const p2 = new Promise(resolve => setTimeout(() => resolve('快'), 100));
 
Promise.race([p1, p2])
  .then(value => console.log(value));  // 输出: 快
 
// 实际场景:请求超时控制
function fetchWithTimeout(url, timeout = 5000) {
  const fetchPromise = fetch(url).then(r => r.json());
  const timeoutPromise = new Promise((_, reject) => 
    setTimeout(() => reject(new Error('请求超时')), timeout)
  );
  
  return Promise.race([fetchPromise, timeoutPromise]);
}
 
// 使用
fetchWithTimeout('/api/data', 3000)
  .then(data => console.log(data))
  .catch(err => console.log(err.message));  // 可能输出: 请求超时
 
// race 也会捕获第一个失败
Promise.race([
  Promise.reject('立即失败'),
  Promise.resolve('稍后成功')
])
.catch(err => console.log(err));  // 输出: 立即失败

3.3 Promise.allSettled() —— 等待所有完成(ES2020) #

等待所有 Promise 完成(无论成功失败),返回每个 Promise 的状态和结果。

// Promise.allSettled 基本用法
const p1 = Promise.resolve('成功1');
const p2 = Promise.reject('失败2');
const p3 = Promise.resolve('成功3');
 
Promise.allSettled([p1, p2, p3])
  .then(results => {
    console.log(results);
    // [
    //   { status: 'fulfilled', value: '成功1' },
    //   { status: 'rejected', reason: '失败2' },
    //   { status: 'fulfilled', value: '成功3' }
    // ]
  });
 
// 实际场景:批量请求,想知道哪些成功哪些失败
function fetchMultipleUrls(urls) {
  const promises = urls.map(url => 
    fetch(url).then(r => r.json()).catch(err => ({ error: err.message }))
  );
  
  return Promise.allSettled(promises)
    .then(results => {
      const succeeded = results.filter(r => r.status === 'fulfilled');
      const failed = results.filter(r => r.status === 'rejected');
      
      console.log(`成功 ${succeeded.length} 个,失败 ${failed.length} 个`);
      return { succeeded, failed };
    });
}

allSettled vs all 对比:

方法 一个失败时 返回值格式
Promise.all 整体失败,丢失其他结果 直接值 [v1, v2, v3]
Promise.allSettled 继续等待其他完成 { status, value/reason }[]

3.4 Promise.any() —— 第一个成功就返回(ES2021) #

等待第一个成功,如果全部失败才整体失败。

// Promise.any 基本用法
const p1 = Promise.reject('失败1');
const p2 = Promise.resolve('成功2');
const p3 = Promise.reject('失败3');
 
Promise.any([p1, p2, p3])
  .then(value => console.log(value));  // 输出: 成功2
 
// 全部失败时
Promise.any([
  Promise.reject('失败1'),
  Promise.reject('失败2')
])
.catch(error => {
  console.log(error);  // AggregateError: All promises were rejected
  console.log(error.errors);  // ['失败1', '失败2']
});
 
// 实际场景:尝试多个镜像源,取最快成功的
function fetchFromMirrors(url) {
  const mirrors = [
    'https://mirror1.com',
    'https://mirror2.com',
    'https://mirror3.com'
  ];
  
  const promises = mirrors.map(mirror => 
    fetch(`${mirror}${url}`).then(r => r.json())
  );
  
  return Promise.any(promises)
    .then(data => data)
    .catch(err => {
      console.log('所有镜像都失败了:', err.errors);
    });
}

3.5 Promise.resolve() / Promise.reject() —— 快捷创建 #

// Promise.resolve —— 创建一个立即成功的 Promise
const p1 = Promise.resolve('数据');
p1.then(value => console.log(value));  // 输出: 数据
 
// 等价于
const p2 = new Promise(resolve => resolve('数据'));
 
// Promise.reject —— 创建一个立即失败的 Promise
const p3 = Promise.reject('错误');
p3.catch(error => console.log(error));  // 输出: 错误
 
// 注意:resolve 如果传入 Promise,会"穿透"
const innerPromise = new Promise(resolve => resolve('内部数据'));
const outerPromise = Promise.resolve(innerPromise);
 
outerPromise.then(value => console.log(value));  // 输出: 内部数据
// 不是输出 innerPromise 对象!

四、静态方法对比速查表 #

方法 等待策略 成功条件 失败条件 返回值
Promise.all 全部完成 全部成功 一个失败 成功值数组
Promise.race 第一个完成 第一个成功 第一个失败 第一个结果
Promise.allSettled 全部完成 不区分 不区分 状态数组
Promise.any 第一个成功 一个成功 全部失败 第一个成功值

选择建议:

场景 推荐方法
批量请求,全部成功才算成功 Promise.all
请求超时控制 Promise.race
批量请求,想知道每条结果 Promise.allSettled
多个镜像源,取最快成功的 Promise.any

五、手写 Promise 实现 #

5.1 手写 Promise 核心类 #

class MyPromise {
  // 三种状态常量
  static PENDING = 'pending';
  static FULFILLED = 'fulfilled';
  static REJECTED = 'rejected';
  
  constructor(executor) {
    // 初始状态
    this.status = MyPromise.PENDING;
    this.value = undefined;      // 成功的值
    this.reason = undefined;     // 失败的原因
    
    // 回调队列(因为可能 then 在 resolve 之前调用)
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];
    
    // resolve 函数
    const resolve = (value) => {
      // 只能改变一次
      if (this.status === MyPromise.PENDING) {
        this.status = MyPromise.FULFILLED;
        this.value = value;
        
        // 执行所有成功回调
        this.onFulfilledCallbacks.forEach(cb => cb(this.value));
      }
    };
    
    // reject 函数
    const reject = (reason) => {
      if (this.status === MyPromise.PENDING) {
        this.status = MyPromise.REJECTED;
        this.reason = reason;
        
        // 执行所有失败回调
        this.onRejectedCallbacks.forEach(cb => cb(this.reason));
      }
    };
    
    // 立即执行 executor(可能抛出错误)
    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }
  
  // then 方法
  then(onFulfilled, onRejected) {
    // 参数校验:如果不是函数,就穿透传值
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
    
    // 返回新 Promise(链式调用的关键)
    const promise2 = new MyPromise((resolve, reject) => {
      
      // 成功状态 —— 立即执行
      if (this.status === MyPromise.FULFILLED) {
        // 异步执行(模拟微任务)
        setTimeout(() => {
          try {
            const x = onFulfilled(this.value);
            // 处理返回值(可能是 Promise)
            this.resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }
      
      // 失败状态 —— 立即执行
      if (this.status === MyPromise.REJECTED) {
        setTimeout(() => {
          try {
            const x = onRejected(this.reason);
            this.resolvePromise(promise2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        }, 0);
      }
      
      // pending 状态 —— 存入队列(异步执行时再调用)
      if (this.status === MyPromise.PENDING) {
        this.onFulfilledCallbacks.push((value) => {
          setTimeout(() => {
            try {
              const x = onFulfilled(value);
              this.resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });
        
        this.onRejectedCallbacks.push((reason) => {
          setTimeout(() => {
            try {
              const x = onRejected(reason);
              this.resolvePromise(promise2, x, resolve, reject);
            } catch (error) {
              reject(error);
            }
          }, 0);
        });
      }
    });
    
    return promise2;
  }
  
  // 处理返回值(Promise A+ 规范的核心)
  resolvePromise(promise2, x, resolve, reject) {
    // 循环引用检测
    if (promise2 === x) {
      return reject(new TypeError('循环引用'));
    }
    
    // x 是 Promise
    if (x instanceof MyPromise) {
      x.then(
        value => this.resolvePromise(promise2, value, resolve, reject),
        reject
      );
    }
    // x 是对象或函数(可能有 then 方法)
    else if (typeof x === 'object' && x !== null || typeof x === 'function') {
      let then;
      try {
        then = x.then;
      } catch (error) {
        return reject(error);
      }
      
      // 如果 then 是函数,认为是 Promise-like
      if (typeof then === 'function') {
        let called = false;  // 防止多次调用
        try {
          then.call(
            x,
            (y) => {
              if (called) return;
              called = true;
              this.resolvePromise(promise2, y, resolve, reject);
            },
            (r) => {
              if (called) return;
              called = true;
              reject(r);
            }
          );
        } catch (error) {
          if (called) return;
          reject(error);
        }
      } else {
        resolve(x);  // 普通对象
      }
    }
    // x 是普通值
    else {
      resolve(x);
    }
  }
  
  // catch 方法
  catch(onRejected) {
    return this.then(undefined, onRejected);
  }
  
  // finally 方法
  finally(onFinally) {
    return this.then(
      value => {
        onFinally();
        return value;
      },
      reason => {
        onFinally();
        throw reason;
      }
    );
  }
  
  // 静态方法:resolve
  static resolve(value) {
    // 如果已经是 Promise,直接返回
    if (value instanceof MyPromise) {
      return value;
    }
    return new MyPromise(resolve => resolve(value));
  }
  
  // 静态方法:reject
  static reject(reason) {
    return new MyPromise((_, reject) => reject(reason));
  }
}
 
// 测试 MyPromise
const p = new MyPromise((resolve, reject) => {
  setTimeout(() => resolve(10), 100);
});
 
p.then(value => {
  console.log('第一次:', value);  // 10
  return value * 2;
})
.then(value => {
  console.log('第二次:', value);  // 20
  return new MyPromise(resolve => resolve(value + 5));
})
.then(value => {
  console.log('第三次:', value);  // 25
})
.catch(err => {
  console.log('错误:', err);
});

5.2 手写 Promise.all() #

// 手写 Promise.all
MyPromise.all = function(promises) {
  return new MyPromise((resolve, reject) => {
    // 输入校验
    if (!Array.isArray(promises)) {
      return reject(new TypeError('promises must be an array'));
    }
    
    const results = [];
    let completedCount = 0;
    const total = promises.length;
    
    // 空数组直接返回空数组
    if (total === 0) {
      return resolve(results);
    }
    
    promises.forEach((promise, index) => {
      // 确保每个元素都是 Promise
      MyPromise.resolve(promise).then(
        (value) => {
          results[index] = value;  // 保持顺序
          completedCount++;
          
          // 全部完成
          if (completedCount === total) {
            resolve(results);
          }
        },
        (reason) => {
          reject(reason);  // 一个失败,整体失败
        }
      );
    });
  });
};
 
// 测试
MyPromise.all([
  MyPromise.resolve(1),
  MyPromise.resolve(2),
  MyPromise.resolve(3)
])
.then(values => console.log('all 结果:', values));  // [1, 2, 3]

5.3 手写 Promise.race() #

// 手写 Promise.race
MyPromise.race = function(promises) {
  return new MyPromise((resolve, reject) => {
    if (!Array.isArray(promises)) {
      return reject(new TypeError('promises must be an array'));
    }
    
    // 空数组永远 pending(标准行为)
    if (promises.length === 0) {
      return;  // 永不 resolve 或 reject
    }
    
    promises.forEach(promise => {
      MyPromise.resolve(promise).then(resolve, reject);  // 第一个完成就返回
    });
  });
};
 
// 测试
MyPromise.race([
  new MyPromise(resolve => setTimeout(() => resolve('慢'), 300)),
  new MyPromise(resolve => setTimeout(() => resolve('快'), 100))
])
.then(value => console.log('race 结果:', value));  // 快

5.4 手写 Promise.allSettled() #

// 手写 Promise.allSettled
MyPromise.allSettled = function(promises) {
  return new MyPromise((resolve) => {
    if (!Array.isArray(promises)) {
      return resolve([]);  // 按标准,返回空数组
    }
    
    const results = [];
    let settledCount = 0;
    const total = promises.length;
    
    if (total === 0) {
      return resolve(results);
    }
    
    promises.forEach((promise, index) => {
      MyPromise.resolve(promise).then(
        (value) => {
          results[index] = { status: 'fulfilled', value };
          settledCount++;
          if (settledCount === total) {
            resolve(results);
          }
        },
        (reason) => {
          results[index] = { status: 'rejected', reason };
          settledCount++;
          if (settledCount === total) {
            resolve(results);
          }
        }
      );
    });
  });
};
 
// 测试
MyPromise.allSettled([
  MyPromise.resolve('成功'),
  MyPromise.reject('失败')
])
.then(results => console.log('allSettled 结果:', results));
// [{ status: 'fulfilled', value: '成功' }, { status: 'rejected', reason: '失败' }]

5.5 手写 Promise.any() #

// 手写 Promise.any
MyPromise.any = function(promises) {
  return new MyPromise((resolve, reject) => {
    if (!Array.isArray(promises)) {
      return reject(new TypeError('promises must be an array'));
    }
    
    const errors = [];
    let rejectedCount = 0;
    const total = promises.length;
    
    // 空数组直接 reject
    if (total === 0) {
      return reject(new AggregateError([], 'All promises were rejected'));
    }
    
    promises.forEach((promise, index) => {
      MyPromise.resolve(promise).then(
        resolve,  // 第一个成功就直接返回
        (reason) => {
          errors[index] = reason;
          rejectedCount++;
          
          // 全部失败
          if (rejectedCount === total) {
            reject(new AggregateError(errors, 'All promises were rejected'));
          }
        }
      );
    });
  });
};
 
// AggregateError 类(如果环境不支持)
class AggregateError extends Error {
  constructor(errors, message) {
    super(message);
    this.errors = errors;
    this.name = 'AggregateError';
  }
}
 
// 测试
MyPromise.any([
  MyPromise.reject('失败1'),
  MyPromise.resolve('成功2'),
  MyPromise.reject('失败3')
])
.then(value => console.log('any 结果:', value));  // 成功2

六、常见问题与陷阱 #

Q1: then 的返回值是什么? #

// then 总是返回一个新的 Promise
const p1 = new Promise(resolve => resolve(1));
const p2 = p1.then(value => value + 1);
 
console.log(p1 === p2);  // false,是两个不同的 Promise
 
// 这就是链式调用的原理
p1.then(v1 => v1 + 1)
  .then(v2 => v2 * 2)   // 这是新 Promise 的 then
  .then(v3 => console.log(v3));

Q2: Promise 和 async/await 的关系? #

async/await 是 Promise 的语法糖,本质还是 Promise。

// async/await 写法
async function fetchData() {
  try {
    const user = await getUserInfo(userId);
    const orders = await getUserOrders(user.id);
    return orders;
  } catch (error) {
    console.error(error);
  }
}
 
// 等价的 Promise 写法
function fetchData() {
  return getUserInfo(userId)
    .then(user => getUserOrders(user.id))
    .catch(error => console.error(error));
}
 
// async 函数返回 Promise
async function hello() {
  return 'hello';
}
hello().then(value => console.log(value));  // hello

Q3: Promise 的错误会"吞掉"吗? #

// 未捕获的 Promise 错误不会中断程序,但会静默失败
const p = Promise.reject('错误');
// 没有 catch,程序继续运行,但会有警告
 
// 最佳实践:总是添加 catch
Promise.reject('错误')
  .catch(err => console.error(err));
 
// 或使用 unhandledrejection 事件(全局捕获)
window.addEventListener('unhandledrejection', event => {
  console.error('未捕获的 Promise 错误:', event.reason);
});

Q4: 如何让 Promise 可以取消? #

// Promise 本身不能取消,但可以用 race 模拟
function makeCancelable(promise) {
  let canceled = false;
  
  const cancelPromise = new Promise((_, reject) => {
    setTimeout(() => {
      if (canceled) {
        reject(new Error('已取消'));
      }
    }, 0);
  });
  
  return {
    promise: Promise.race([promise, cancelPromise]),
    cancel() {
      canceled = true;
    }
  };
}
 
// 使用
const { promise, cancel } = makeCancelable(fetch('/api/data'));
promise.then(data => console.log(data)).catch(err => console.log(err));
cancel();  // 手动取消

Q5: Promise 执行顺序是怎样的? #

console.log('1. 同步开始');
 
const p = new Promise(resolve => {
  console.log('2. Promise executor(同步执行)');
  resolve();
});
 
p.then(() => {
  console.log('4. then 回调(微任务)');
});
 
console.log('3. 同步结束');
 
// 输出顺序:1 → 2 → 3 → 4
// executor 是同步执行的!then 回调是微任务(异步)

七、总结速记 #

核心方法速查 #

方法 作用 返回值
then(onFulfilled, onRejected) 处理结果 新 Promise
catch(onRejected) 捕获错误 新 Promise
finally(onFinally) 清理工作 新 Promise

静态方法速查 #

方法 等待策略 成功返回 失败返回
Promise.all 全部完成 [v1, v2...] 第一个错误
Promise.race 第一个完成 第一个值 第一个错误
Promise.allSettled 全部完成 [{status, value/reason}...] 不会失败
Promise.any 第一个成功 第一个成功值 AggregateError

手写 Promise 核心要点 #

  1. 三种状态:pending、fulfilled、rejected,只能改一次
  2. 回调队列:then 可能先于 resolve 调用,需要存队列
  3. 链式调用:then 返回新 Promise,resolvePromise 处理返回值
  4. 异步执行:回调用 setTimeout 模拟微任务
  5. 循环引用检测:防止 promise.then(() => promise) 歪死循环

最佳实践 #

场景 建议
所有 Promise 一定要有 .catch()
批量请求 Promise.allPromise.allSettled
超时控制 Promise.race
清理工作 .finally()
复杂异步流 用 async/await 更清晰

附录:完整代码仓库 #

本文所有代码示例均可直接运行,建议创建测试文件实践:

// test-promise.js
// 复制上述手写代码,运行测试
 
// 运行
node test-promise.js

最后更新:2026-03-31