Promise常用API总结

Promise 常用 API 总结

一、全景图

Promise
├─ 实例方法(promise.xxx)
│   ├─ then(onFulfilled, onRejected) → 新 Promise
│   ├─ catch(onRejected)             → 新 Promise(= then(undefined, onRejected))
│   └─ finally(onFinally)            → 新 Promise(不接收值,原样透传)
│
└─ 静态方法(Promise.xxx)
    ├─ Promise.resolve(value)        → 快速创建已成功的 Promise
    ├─ Promise.reject(reason)        → 快速创建已失败的 Promise
    ├─ Promise.all([...])            → 全部成功才成功,一个失败立即失败
    ├─ Promise.allSettled([...])     → 永不失败,等所有都敲定,返回各自状态
    ├─ Promise.race([...])           → 第一个"敲定"的(成功或失败都算)
    ├─ Promise.any([...])            → 第一个"成功"的,全失败才失败
    └─ Promise.withResolvers()       → ES2024,一把拿到 promise + resolve + reject

二、实例方法

1. then(onFulfilled?, onRejected?)

  • 返回新 Promise(所以能链式调用)
  • 回调的返回值决定新 Promise 的状态:
    • 返回普通值 → 新 Promise 成功,值为该值
    • 返回 Promise → 跟随它的状态
    • 抛异常 → 新 Promise 失败
Promise.resolve(1)
  .then(v => v + 1)        // 2
  .then(v => Promise.resolve(v * 10))  // 20(跟随返回的 Promise)
  .then(v => { throw new Error('boom') })
  .catch(e => console.log(e.message))  // boom

2. catch(onRejected)

本质是 then(undefined, onRejected),捕获链上之前所有环节的错误(错误冒泡)。

// ⚠️ 区别
p.then(fn, errFn)   // errFn 只能捕获 p 自身的失败,捕获不到 fn 里抛的错
p.then(fn).catch(errFn)  // ✅ 能捕获 p 失败 + fn 里抛的错(推荐)

3. finally(onFinally)

  • 无论成功失败都执行(关闭 loading、释放资源)
  • 不接收参数,且不改变结果(返回值被忽略,原样透传)
p.finally(() => loading.value = false)   // ✅ 拿不到 data

三、静态方法(重点)

1. Promise.resolve(value) / Promise.reject(reason)

Promise.resolve(1)              // 成功,值 1
Promise.resolve(existingPromise) // 原样返回(不包装)
Promise.reject(new Error('x'))  // 失败

常用于:把同步值统一成 Promise、async 函数的返回值包装。

2. Promise.all([...]) —— 全部成功才成功

const [user, list] = await Promise.all([getUser(), getList()])
  • 结果数组顺序 = 输入顺序,不是完成顺序 ⭐(常考)
  • 快速失败:任一 reject → 整体立即 reject(其他请求不会取消,只是结果被丢弃)
  • 典型:并行请求,缺一不可

3. Promise.allSettled([...]) —— 永不失败

const res = await Promise.allSettled([a(), b(), c()])
// [
//   { status: 'fulfilled', value: 1 },
//   { status: 'rejected',  reason: Error }
// ]
res.filter(r => r.status === 'fulfilled').map(r => r.value)
  • 等所有都敲定(fulfilled 或 rejected)
  • 典型:批量提交/批量导出,允许部分失败要统计

4. Promise.race([...]) —— 第一个敲定的(不分成败)

// 超时控制(经典)
const withTimeout = (p, ms) => Promise.race([
  p,
  new Promise((_, rej) => setTimeout(() => rej(new Error('timeout')), ms)),
])
  • 谁先敲定(成功或失败都算)就用谁
  • 空数组 → 永远 pending ⚠️

5. Promise.any([...]) —— 第一个成功的

const fastest = await Promise.any([cdn1(), cdn2(), cdn3()])
  • 忽略失败,取第一个 fulfilled
  • 全部失败 → reject AggregateError(err.errors 是所有原因)
  • 空数组 → 立即 AggregateError
  • 典型:多源备份,取最快可用

6. Promise.withResolvers()(ES2024)

const { promise, resolve, reject } = Promise.withResolvers()
// 不用再写 new Promise((res, rej) => { ...res = resolve... }) 这种外部赋值

典型:把"回调式/事件式"API 包成 Promise(如先把 resolve 存到外部,等某个事件触发再调用)。


四、对比表(背这张)

API 何时成功 何时失败 返回值 典型场景
all 全部成功 任一失败立即失败 结果数组(按输入顺序) 并行请求,缺一不可
allSettled 总是成功 从不失败 {status, value/reason}[] 批量操作,允许部分失败
race 第一个敲定者成功 第一个敲定者失败 单个值 超时控制、竞速
any 第一个成功 全部失败才失败(AggregateError) 单个值 多源备份取最快

五、易错点清单

  1. all 的结果顺序 = 输入顺序,不是谁先返回谁排前面。
  2. all 快速失败但不会取消其他请求(要真取消得用 AbortController)。
  3. race([]) 永远 pending;any([]) 立即 AggregateError。
  4. 非 Promise 值会被自动包装:Promise.all([1, p]) 里的 1 等价于 Promise.resolve(1)。
  5. catch 放最后:p.then(a).then(b).catch(handle),一个 catch 兜住整条链。
  6. then 里抛的错只有后面的 catch 能接住,then(onOk, onErr) 的 onErr 接不到。
  7. all 不做并发限制:100 个请求会一起发出,需要限流要自己写并发池(阶段 10.2)。
  8. finally 拿不到值,也改不了结果,只做清理。

六、速记口诀

all 全成才成、一败即败;allSettled 永不败、看状态;race 抢第一(成败都算);any 抢第一个成功。
顺序看输入,失败看策略,超时用 race,部分成功用 allSettled。

posted @ 2026-10-13 17:55  寅信  阅读(4)  评论(0)    收藏  举报