怎么避免 Promise.all 其中一个 reject 让所有都取不到值

6 篇文章 0 订阅

大家都知道 Promise.all 传入的 promise array 里面,只要有其中一个 promise reject 了,即使它前面的 promise 正常 fulfilled,整个 promise.all 也会直接走到 catch,并且只会 catch 第一个 reject 的返回值。

那如何让一串 promise 用 Promise.all 实现并行不阻塞地调用,同时每个的 reject 和 fulfilled 状态不互相影响呢?

 

答案是将这串 promise,每个都用一个新 promise 包裹一下。无论内部原 promise 抛出 reject 还是 fulfilled ,都用外层的 promise resolve 返回。

resolve 返回的信息里再自定义字段来传递原 promise 的成功失败和返回内容即可。

将包裹后的各个 promise 放入 promise.all 中,自然可以保证每个都不会 reject,同时达到并行不阻塞的目的。

 

示例代码如下:

改造前代码:

// Promise.all 调用:只要其中一个报错,就得到 [undefined, undefined, undefined]
const [res1, res2, res3] = await Promise.all([
    somePromise1,
    somePromise2,
    somePromise3
  ])

改造后代码: 


// 包裹函数,避免 promise 抛出 reject
const wrapPromise = (promise)=> {
  return new Promise((resolve, reject) => {
    promise
    .then((info) => resolve({ isok: true, info }))
    .catch((err) => resolve({ isok: false, err }))
  })
}


// Promise.all 调用
 const resArr = await Promise.all([
    // 全部使用 wrapPromise 包裹
    wrapPromise(somePromise1),
    wrapPromise(somePromise2),
    wrapPromise(somePromise3)
  ])
  const [res1, res2, res3] = resArr.map((res) => {
    if (res.isok) {
      // 处理 fulfilled promise 结果的逻辑
      return res.info
    } else {
      // 处理 rejected promise 结果的逻辑
      console.error(res.err)
      return {}
    }
  })

 

 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Promise.all是JavaScript中的一个方法,用于将多个Promise对象封装成一个新的Promise对象。它接受一个Promise对象数组作为参数,返回一个新的Promise对象。当所有Promise对象都成功时,新的Promise对象也会成功,并返回所有Promise对象的返回组成的数组。如果有任意一个Promise对象失败,新的Promise对象也会失败,并返回第一个失败的Promise对象的错误信息。 示例: ``` Promise.all([promise1, promise2, promise3]) .then((values) => { console.log(values); }) .catch((error) => { console.log(error); }); ``` ### 回答2: 对于这个问题,我将提供一个300字的回答来介绍如何封装一个 Promise.all函数。 Promise.all是一个用于处理多个 Promise 对象的静态方法,它接受一个 Promise 对象数组作为参数,并返回一个新的 Promise 对象。当传入的 Promise 对象数组中的所有 Promise 对象都变为 resolved 状态时,这个新的 Promise 对象才会被 resolve,并传递一个包含所有 resolved 的数组。如果传入的 Promise 对象数组中有任一一个 Promise 对象被 reject,则新的 Promise 对象将被 reject,并传递第一个 reject 。 要封装一个 Promise.all函数,我们可以创建一个新的 Promise 对象,并在其中进行相关的处理逻辑。首先,我们需要判断传入的参数是否为一个 Promise 对象数组,如果不是,则直接返回一个被 rejectPromise 对象,并传递一个对应的错误信息。 接下来,我们可以使用一个计数器来统计所有 Promise 对象的 resolved 状态。我们可以使用一个变量来保存所有 resolved ,并在每个 Promise 对象 resolve 时将其添加到这个变量里。同时,在任何一个 Promise 对象被 reject 时,我们需要立即 reject 整个新的 Promise 对象,并传递对应的 reject 。 最后,当所有 Promise 对象都变为 resolved 状态时,我们可以 resolve 新的 Promise 对象,并传递保存的所有 resolved 。 总结起来,封装一个 Promise.all函数需要进行参数验证、计数器和变量的初始化、处理每个 Promise 对象的 resolved 和 reject 状态,并最终返回一个新的 Promise 对象。这个过程可以通过创建一个匿名函数,使用上述逻辑来实现。这样我们就能够使用封装好的 Promise.all函数来处理多个 Promise 对象的结果了。 ### 回答3: Promise.all 是 JavaScript 中的一个方法,它接收一个 Promise 数组作为参数,并在所有 Promise 都完成时返回一个新的 Promise 对象。 如果要封装一个 Promise.all 方法,可以采用以下的方式: ```javascript function myPromiseAll(promises) { return new Promise((resolve, reject) => { let results = []; let counter = 0; if (promises.length === 0) { resolve(results); } else { for (let i = 0; i < promises.length; i++) { promises[i].then((result) => { results[i] = result; counter++; if (counter === promises.length) { resolve(results); } }).catch((error) => { reject(error); }); } } }); } ``` 这个方法首先创建一个新的 Promise 对象,并接收一个 promises 数组作为参数。然后创建一个空数组来存储每个 Promise 的结果,以及一个计数器来跟踪已完成的 Promise 数量。 接下来,判断传入的 promises 数组是否为空。如果为空,直接使用 resolve 返回空数组。 如果 promises 数组不为空,循环遍历数组中的每个 Promise 对象。当每个 Promise 对象都调用了 then 方法时,将该 Promise 的结果存储到 results 数组的对应位置中,并增加计数器的。当计数器的等于 promises 数组的长度时,说明所有 Promise 已经完成,此时使用 resolve 返回结果数组。 如果其中任意一个 Promise 出现错误,则使用 catch 方法将错误传递给新的 Promise 对象,并使用 reject 返回错误。 这样,我们就成功封装了一个 Promise.all 方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值