我想在NodeJS
中并行处理多个异步调用。如果这些调用中的特定数量得到解决或者全部完成(一些得到解决,一些被拒绝),我可以继续。如何做到这一点?Promise.All()
在完成所有承诺时进行解析,Promise.Any()
在解析任何一个承诺或拒绝所有承诺时进行解析。是否可以等待50%的承诺或n
数量的承诺得到解析,而不是等待所有承诺得到解析。
我想在NodeJS
中并行处理多个异步调用。如果这些调用中的特定数量得到解决或者全部完成(一些得到解决,一些被拒绝),我可以继续。如何做到这一点?Promise.All()
在完成所有承诺时进行解析,Promise.Any()
在解析任何一个承诺或拒绝所有承诺时进行解析。是否可以等待50%的承诺或n
数量的承诺得到解析,而不是等待所有承诺得到解析。
4条答案
按热度按时间ldxq2e6h1#
您可以编写一个函数,为每个给定的
Promise
附加一个then回调,每次递增计数(或将结果推送到数组),并在计数达到某个值时进行解析。一个基本示例:
pn9klfpd2#
首次尝试
很难想象函数的用例,但这是一个有趣的问题。
firstN
接受一个Array<Promise<T>>
和一个数字n
。它解析一个Map<number, T>
,其中数字对应于输入数组中的promise索引。您可以在typescript操场上验证-为了测试它,我们将模拟一个
pass
和fail
函数,它们在ms
毫秒之后解析-现在做出承诺解决前三个问题-
最先解决的是最短的10、40和50,键1、7和4对应于它们在输入中的位置,最重要的是,注意总运行时间等于一串中承诺时间最长的一个--
在第二个测试中,我们将确保当不充分的承诺解决时适当的失败。在这个测试中,10个承诺中有8个失败,使得不可能实现
n=3
-只有80和100通过,一旦90失败,我们的职能有足够的信息知道不可能成功,并提供早期拒绝-
在我们的第三个测试中,我们验证
n=0
是否立即退出以及空Map -是否正确返回最后,我们测试
n
超过提供的承诺数的场景,我们看到立即拒绝并显示适当的消息-第二次尝试
最初,我考虑将Set和Map作为在循环中利用
Promise.race
的方法。在完成程序的初稿后,我进行了重构,并通过了上述测试,降低了实现复杂性-r7knjye23#
下面是另一个例子:
firstn
promise的行为有点像Promise.all()
,一旦第一个n
promise被解析,它就会被解析,并提供一个对象:对于所有非零值,表达式
!--n
递减(本地)计数器n
并返回false
。更新:在@Bergi的评论之后,我现在也加入了一个适当的拒绝处理。如果一开始要求太多的解析(
n>parr.length
),那么firstn
承诺将立即拒绝。否则m=parr.length-n+1
将在每个单独的承诺被拒绝后递减,并且一旦m==0
主(firstn
)承诺也将被拒绝。@Wyck建议使用确定性函数而不是
Math.random()
来进行单元测试。好的,下面是一个带有简单伪随机数生成器的版本:x一个一个一个一个x一个一个二个x
意见:
我用
"1-"
和"2-"
作为这两个运行的承诺名称的前缀。由于第二个运行在第一个firstN
-promise被解决后就已经开始了,所以第一个运行的其余单个承诺将在第二个运行期间继续被解决/拒绝。y0u0uwnf4#
Promise.allSettled()
接受一个异步调用数组。您不能先添加50%的调用,然后再添加其他50%。它将返回一个数组,其中包含结果和状态[已拒绝或已解决]