从Promise的catch中向现有的Promises.all数组添加内容

3

我有一段代码,在其中向一个promise数组添加了一些异步操作,并调用Promise.all来解决所有操作并等待结果。 我期望检查第二个操作是否失败,如果是这样,从catch块中执行第一个操作。 如果我将catch块附加到此数组中的某个promise并执行异步操作,我是否可以将其添加到同一promise数组中,还是最好单独等待此操作。

const promises = [];
promises.push(performAsync1(record))
promises.push(performAsync2().catch(() =>
   console.error("Async2 Failed");
   promises.push(performAsync1(failedRecord));
}
const responses = await Promise.all(promises);

3
那么你如何使用 responses?为什么不直接使用 Promise 链 promises.push(performAsync2().catch(() => performAsync1())) - Yury Tarabanko
1
不行。如果您在 Promise.all() 调用之后异步添加它,则不会被 Promise.all 捕获。 - Bergi
1个回答

2
这可能因为主要基于观点而被关闭,但我会将performAsync2操作/重试组合分配给变量。
const performAsync2Retrying = performAsync2(record).catch(()=> performAsync1(record))
const promises = []
promises.push(performAsync1(record))
promises.push(performAsync2Retrying)
const responses = await Promise.all(promises)

这使得你的promise数组构建更易于阅读,具有单一职责。
用更现代的措辞来表达这个意思,好处就更加明显了:
const performAsync2Retrying = performAsync2(record).catch(()=> performAsync1(record))
const responses = await Promise.all([performAsync1(record),
    performAsync2Retrying])

但是我真正想做的是通过一个辅助函数来避免引入额外的名称,该函数在第一个函数失败时执行第二个函数(可以进一步详细说明以处理多个参数)。

const retryWith = (f1, f2, _in) => f1(_in).catch(_=>f2(_in))

const responses = await Promise.all([
    performAsync1(record),
    retryWith(performAsync2, performAsync1, record)
 ])

然后我就不需要再考虑如何处理这种情况了。


为什么要引入一个只被调用一次的额外辅助函数呢?我不明白它如何能提高清晰度。 - Bergi
1
我发现这样更容易阅读。保持原样会邀请其他人将更多这样复杂的结构添加到 promise 数组中。如果你经常这样做,你可能想创建一个通用的帮助函数。这是一个品味问题。 - Robert Moskal
我认为将Promise存储在临时变量中没有任何问题,但是为什么要使用函数呢?(当然,为了增加可读性,您还可以将数组构建为具有两个元素的单个文字,而不是使用“push”)。 - Bergi
将捕获构造放入文字中会很糟糕,这正是我结束帖子的方式。你说得对,将承诺分配给变量比我所做的更好。最好的方法是像retryWith(f1, f2)这样的函数,但这也是品味问题。 - Robert Moskal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接