Promise.any()和Promise.first()有什么区别?

时间:2019-12-28 17:01:08

标签: promise

它们看上去几乎相同,但是have different descriptions such as on the book You Don't Know JS

难道他们俩都在不关心任何拒绝的情况下尝试获得第一个已解决的答案(或收到第一个成功的解决方法的通知)吗?

4 个答案:

答案 0 :(得分:2)

您所引用的文章提供了.first()的实现,还提供了.any().first()的定义:

  
      
  • any([ .. ])all([ .. ])相似,但是它会忽略所有拒绝,因此只需要一个就可以完成,而不是全部。
  •   
  • first([ .. ])就像是any([ .. ])的竞赛,这是因为它忽略了任何拒绝,并在第一个Promise实现后立即实现。
  •   

any的定义似乎与EcmaScript的第3阶段中的the one不同。引用的any定义似乎正在等待所有承诺得到解决。返回的诺言只有在所有全部被拒绝时才会被拒绝,但是,如果至少实现了一个诺言,则将兑现-忽略拒绝。

短语“所以只有一个人需要履行,而不是全部满足”。有点令人困惑,但是与.all()的比较不是关于何时结果会稳定下来,但会在什么条件下满足?

答案 1 :(得分:2)

该参考书将.first()描述为解决了第一个已解决的诺言,并忽略了拒绝,并展示了一个永不拒绝的实现。通过自己的承认,如果您通过的所有诺言都被拒绝,它就不会结算返回的诺言。这使得它在实践中几乎毫无用处,并且该书承认它“将其作为练习供读者阅读”以这种方式完成了实现。

本书参考文献并未真正完全或不同地描述.any(),也未显示实施方案。但是,有一个.any()的拟议标准(下面将详细介绍),该标准在首次实现时会实现,或者仅在所有承诺均被拒绝时才拒绝。因此,实际的.any()规范与书籍.first()不同,因为如果所有的承诺都被拒绝,.any()也会被拒绝。


我认为,最容易理解Promise.xxx()选项和提议的概况,因为您可以看到它们如何相互融合。

对于拟议的标准,这是一个有用的图表,总结如下:

enter image description here

Promise.all()

ES2015的一部分。等待所有诺言兑现,第一次拒绝就拒绝。

Short-circuit       Yes 
Short-circuits on   First Rejection
Fulfilled on        All Promises Fulfilled
Rejected on         First Rejection
Resolves with       Array of resolved values
Rejects with        Reason for first rejection

Promise.race()

ES2015的一部分。履行或拒绝的第一个承诺决定了解决的值或拒绝的原因。

Short-circuit       Yes 
Short-circuits on   First Settled
Fulfilled on        First Fulfilled
Rejected on         First Rejection
Resolves with       First resolved value
Rejects with        First rejected reason

Promise.allSettled()

ES2020的一部分(将于2019年底实施)。当所有诺言都兑现时解决(无论已解决还是被拒绝)。它使用对象数组来解析。每个对象都有一个.status属性,该属性设置为字符串值"fulfilled""rejected"。如果fulfilled,则存在.value属性。如果rejected,则存在.reason属性。这种回报的承诺永远不会拒绝。

如果您想知道所有承诺何时完成,然后检查其所有状态,请使用Promise.allSettled()。这不会以任何方式短路。它等待着每一个诺言完成。

这是stage 4 ECMAScript proposal,正在实施中(已经存在于Chrome,Firefox和node.js中)。

Short-circuit       No 
Short-circuits on   None
Fulfilled on        All Fulfilled
Rejected on         Never
Resolves with       Array of objects
Rejects with        Never

Promise.any()

建议用于将来的ECMAScript版本。如果列表中的任何承诺都实现了(无论是否首先发生了拒绝),那么它将以该第一个实现值来解决。仅当所有的诺言都被拒绝而没有一个都实现并且拒绝原因是包含所有拒绝原因的AggregateError类时,才拒绝。当第一个承诺实现时,将以该实现值解决。

Promise.any()的一个用例是,如果您有N个服务可以从中得到响应,而您只想从第一个成功的服务中获得价值。您向所有N个用户发出请求,并且Promise.any()会在N个用户中的任何一个成功时解决。

Promise.any()当前是ECMAScript的stage 3 proposal

Short-circuit       Yes 
Short-circuits on   First Fulfilled
Fulfilled on        First Fulfilled
Rejected on         All Reject
Resolves with       First Resolved Value
Rejects with        AggregateError reason

仅供参考,截至2019年12月,其余有关此实现的标准的讨论似乎是关于AggregateError类的详细信息,以及属性是吸气剂还是“自有”属性,以及哪些属性是可枚举的,以及如何枚举。与其他地方的工作方式不一致。


Promise.first()

仅来自书籍。这似乎并不是特别有用,并且不在标准轨道上。文本本身描述了它的问题,即如果所有的诺言都被拒绝,它就永远不会解决或拒绝。

它的工作方式类似于为Promise.any()提议的标准(在解决第一个诺言时解决,忽略拒绝),但是,如果所有诺言都被拒绝,它什么也不做,从不解决或拒绝,而是“将其作为练习读者”来完成此操作。

Short-circuit       Yes 
Short-circuits on   First Fulfilled
Fulfilled on        First Fulfilled
Rejected on         Never 
Resolves with       First Resolved value
Rejects with        Never

答案 2 :(得分:0)

根据MDN,没有Promise.first

您不知道JS的书提到过:

  

虽然本机ES6 Promises带有内置的Promise.all([..])和Promise.race([..]),但还有其他几种常用模式,其语义有所不同:

原生ES6仅支持Promise.anyPromise.allPromise.any is not supported by all browsers

只要承诺中的任何承诺得到解决,

Promise.any就会解决。也称为latch解决胜利的第一个。

Promise.all将在所有承诺中的所有承诺均得到解决时解决。虽然没有特定的顺序可以兑现承诺。如果任何承诺被拒绝,那么Promise.all将拒绝被拒绝承诺的原因。这也称为gate主要承诺,直到所有承诺都得到解决后才能解决。

答案 3 :(得分:0)

差异似乎是,MDN定义的Promise.any()reject解决,如果您所链接的书中实现的Promise.first()不会被拒绝点。否则我看不出任何区别。