Promise.all API 的出错处理

举报
Jerry Wang 发表于 2023/01/01 09:38:03 2023/01/01
【摘要】 如果任何一个 Promise 被 reject,Promise.all 返回的 Promise 会立即拒绝该错误。

如果任何一个 Promise 被 reject,Promise.all 返回的 Promise 会立即拒绝该错误。

以下是一个例子:

Promise.all([
  new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
  new Promise((resolve, reject) => setTimeout(() => reject(new Error("Whoops!")), 2000)),
  new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).catch(alert); // Error: Whoops!

会打印:Error: Whoops!

这里第二个 Promise 在两秒钟内被拒绝。 这导致立即拒绝 Promise.all,因此 .catch 执行:拒绝错误成为整个 Promise.all 的结果。

如果一个 Promise 被 reject,Promise.all 会立即被 reject ,此时完全忽略列表中的其他 Promise——其结果被忽略了。

例如,如果有多个 fetch 调用,就像上面的例子一样,一个失败了,其他的 fetch 仍然会继续执行,但是 Promise.all 不会再监视它们了。 他们的结果将被忽略。

Promise.all 不会 cancel 这些 Promise 对象,因为 Promise 中没有 cancel 的概念。

技术上说,存在可以帮助解决此问题的 AbortController,但它不是 Promise API 的一部分。

通常, Promise.all(…) 接受一个可迭代的(在大多数情况下是一个数组)的 Promise. 但是,如果这些对象中的任何一个不是 Promise,它就会 按原样 传递给结果数组。

例如,这里的结果是 [1, 2, 3]:

下面是一个例子:

Promise.all([
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(1), 1000)
  }),
  2,
  3
]).then(alert); // 1, 2, 3

如果任何一个 Promise 被拒绝,Promise.all 将作为一个整体被 reject.

当我们需要所有结果成功才能继续时,这对于“全有或全无”的情况很有用:

Promise.all([
  fetch('/template.html'),
  fetch('/style.css'),
  fetch('/data.json')
]).then(render); // render method needs results of all fetches

这从原理上说,有点像数据库操作中的原子操作 概念。

Promise.allSettled 只是等待所有的 Promise 完成,不管结果如何。 结果数组有下列两种情况:

  • {status:"fulfilled", value:result} 成功响应
  • {status:"rejected", reason:error} 表示错误。

例如,我们想获取有关多个 github 用户的信息。 即使一个请求失败,我们仍然对其他请求感兴趣。

这种场景适合使用 Promise.allSettled

let urls = [
  'https://api.github.com/users/iliakan',
  'https://api.github.com/users/remy',
  'https://no-such-url'
];

Promise.allSettled(urls.map(url => fetch(url)))
  .then(results => { // (*)
    results.forEach((result, num) => {
      if (result.status == "fulfilled") {
        alert(`${urls[num]}: ${result.value.status}`);
      }
      if (result.status == "rejected") {
        alert(`${urls[num]}: ${result.reason}`);
      }
    });
  });

传递到 then 回调函数里的输入参数,results 数组为:

[
  {status: 'fulfilled', value: ...response...},
  {status: 'fulfilled', value: ...response...},
  {status: 'rejected', reason: ...error object...}
]

对于每个 Promise 对象,我们要么得到 value 值,要么得到引起错误的 reason 值。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。