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) |
单个值 | 多源备份取最快 |
五、易错点清单
all的结果顺序 = 输入顺序,不是谁先返回谁排前面。all快速失败但不会取消其他请求(要真取消得用AbortController)。race([])永远 pending;any([])立即AggregateError。- 非 Promise 值会被自动包装:
Promise.all([1, p])里的1等价于Promise.resolve(1)。 catch放最后:p.then(a).then(b).catch(handle),一个 catch 兜住整条链。then里抛的错只有后面的catch能接住,then(onOk, onErr)的onErr接不到。all不做并发限制:100 个请求会一起发出,需要限流要自己写并发池(阶段 10.2)。finally拿不到值,也改不了结果,只做清理。
六、速记口诀
all 全成才成、一败即败;allSettled 永不败、看状态;race 抢第一(成败都算);any 抢第一个成功。
顺序看输入,失败看策略,超时用 race,部分成功用 allSettled。

浙公网安备 33010602011771号