Promise 对象本身除了 then、catch、finally 这些实例方法外,还挂载了六个关键静态方法,直接通过 Promise.xxx 调用。它们提供了批量处理、快速创建和逻辑组合的能力,是日常异步编程的瑞士军刀。
Promise.resolve(value)
将任意值转换为一个 已解决(fulfilled) 的 Promise。
- 如果
value是一个普通值,返回一个以该值解决的 Promise。 - 如果
value是一个 Thenable(含有then方法的对象)或 Promise,会 展开 并跟随其最终状态;如果是另一个 Promise,则直接返回该引用(ES6 规范中要求返回一个新的 Promise,但多数引擎会直接返回原对象)。 - 常用于将不确定是同步还是异步的返回值统一为 Promise,便于链式调用。
Promise.resolve(42).then(v => console.log(v)); // 42
const p = Promise.resolve(new Promise(res => setTimeout(() => res('done'), 500)));
p.then(v => console.log(v)); // 500ms 后输出 "done"
实用场景:函数需要返回 Promise,但内部可能根据缓存走同步分支,用
Promise.resolve(data)保证接口一致。
Promise.reject(reason)
创建一个 立即拒绝(rejected) 的 Promise,拒绝原因为 reason。
- 与
resolve不同,参数不会被展开,即使传入的是 Promise 或 Thenable,也会直接作为拒绝理由。
Promise.reject(new Error('something wrong'))
.catch(err => console.log(err.message)); // "something wrong"
实用场景:快速模拟异步失败,或在需要返回拒绝 Promise 的场合(如验证失败)直接生成,而不必
new Promise((_, reject) => reject(...))。
Promise.all(iterable)
接收一个可迭代对象(通常是 Array),返回一个新 Promise:
- 当 所有 Promise 都成功 时,新 Promise 解决,结果是一个包含所有解决值(按原顺序)的数组。
- 只要 任何一个 Promise 失败,新 Promise 立即拒绝,拒绝原因为第一个失败的 Promise 的拒绝理由(其他未结束的请求不会被取消,只是结果被忽略)。
- 如果传入空数组,直接同步解决并返回空数组。
const p1 = Promise.resolve(1);
const p2 = 42; // 不是 Promise,会自动用 Promise.resolve 包裹
const p3 = new Promise(res => setTimeout(() => res(3), 100));
Promise.all([p1, p2, p3]).then(values => {
console.log(values); // [1, 42, 3](等待 p3 完成)
});
// 失败场景
Promise.all([Promise.resolve('ok'), Promise.reject('fail')])
.catch(err => console.log(err)); // 'fail'
实用场景:多个接口并发请求,必须全部成功才能进行下一步(如初始化页面需要同时获取用户信息、配置数据、权限列表)。
Promise.race(iterable)
接收一个可迭代对象,返回一个新 Promise,与第一个 落定(settled) 的 Promise 状态一致(无论是解决还是拒绝)。
const fast = new Promise(res => setTimeout(() => res('fast'), 100));
const slow = new Promise(res => setTimeout(() => res('slow'), 500));
Promise.race([fast, slow]).then(winner => {
console.log(winner); // 100ms 后输出 "fast"
});
如果传入空数组,返回的 Promise 会永远处于 pending 状态(永远不会 resolve 或 reject),因为没有可以用于竞速的成员。
实用场景:请求超时控制 —— 将一个请求与一个延迟 reject 的 Promise 一起竞速,超时则自动拒绝。
function fetchWithTimeout(url, timeout = 5000) {
return Promise.race([
fetch(url),
new Promise((_, reject) => setTimeout(() => reject(new Error('请求超时')), timeout))
]);
}
Promise.allSettled(iterable)
接收一个可迭代对象,返回一个新 Promise,它会 等待所有传入的 Promise 全部落定(不论成功或失败),结果是一个对象数组,每个对象包含:
status:'fulfilled'或'rejected'value:如果 solved,该字段为值reason:如果 rejected,该字段为拒绝原因
这项特性(ES2020)弥补了 all 一票否决的缺陷,非常适合需要知道每个任务结果的场景。
const p1 = Promise.resolve(1);
const p2 = Promise.reject('出错了');
const p3 = Promise.resolve(3);
Promise.allSettled([p1, p2, p3]).then(results => {
results.forEach(r => {
if (r.status === 'fulfilled') {
console.log('成功:', r.value);
} else {
console.log('失败:', r.reason);
}
});
});
// 输出:
// 成功: 1
// 失败: 出错了
// 成功: 3
实用场景:批量上传文件,需要知道每一个文件是上传成功还是失败,以便单独重试失败的,而不是全部重来。
Promise.any(iterable)
接收一个可迭代对象,返回一个新 Promise:
- 只要 任何一个 Promise 成功,返回的 Promise 就以该成功值解决(后续成功的值会被忽略)。
- 如果 所有 Promise 都失败,返回的 Promise 会被拒绝,拒绝理由是一个
AggregateError实例,内部errors属性包含所有拒绝原因。
这是 ES2021 引入的“竞速成功”方法,与 race 的区别在于:race 是第一个落定的,any 是第一个成功的,中间的失败会被自动忽略。
const p1 = new Promise((_, reject) => setTimeout(() => reject('错误1'), 100));
const p2 = new Promise((_, reject) => setTimeout(() => reject('错误2'), 200));
const p3 = new Promise(res => setTimeout(() => res('唯一成功'), 300));
Promise.any([p1, p2, p3]).then(val => {
console.log(val); // 300ms 后输出 "唯一成功"
});
// 全部失败
Promise.any([
Promise.reject('err1'),
Promise.reject('err2')
]).catch(e => {
console.log(e instanceof AggregateError); // true
console.log(e.errors); // ['err1', 'err2']
});
实用场景:从多个 CDN 节点或缓存源获取同一资源,谁最快成功就用谁,全部失败才真正报错。
小总结:
resolve/reject:最基础的值转 Promise 手段all:等待全部成功,一个失败全部失败race:只要最快落定,无论是成功还是失败allSettled:等待全部结束,获取每个结果的状态any:等待第一个成功,全部失败才报错
掌握这些静态方法,就掌握了 Promise 批量操作的精髓,几乎所有复杂的异步并发需求都能通过它们优雅地实现。