人人都会AI编程

静态方法:resolve、reject、all、race、allSettled、any

更新时间:2026-07-11

Promise 对象本身除了 thencatchfinally 这些实例方法外,还挂载了六个关键静态方法,直接通过 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 批量操作的精髓,几乎所有复杂的异步并发需求都能通过它们优雅地实现。