承诺全部解决


在Ecma TC39的第71次会议上,将考虑Promise.allSettled的项目和参考实施,这是Promise.allSettled的四个主要组合中的第三个。


作者 :Jason Williams(BBC),Robert Pumley(彭博),Matthias Binens(Google)
冠军 :Matthias Binens(谷歌)
阶段 :3


对于播客的粉丝,请在YouTube上复制。


介绍与动机


许诺世界中有四个主要的组合器:


  • Promise.all 。 ES2015。 在第一个被拒绝/被拒绝的承诺中关闭。
  • Promise.race 。 ES2015。 在第一个以某种方式解决/解决的诺言时关闭。
  • Promise.any 。 阶段1.在第一个满意/已兑现的承诺时结束。
  • Promise.allSettled 。 阶段3→阶段4。不关闭。

所有这些在普通用户库中都有广泛的表示,它们各自本身都是有用的,并且适用于各种情况。


当您希望在完成许多请求后立即执行操作,而不管它们是成功还是失败,都将发生组合器的主要应用程序。 其余的promises组合器是闭合的( 短路 ),丢弃输入值的结果,这些输入值对于系统的特定状态失去竞争。 Promise.allSettled的独特之处在于,它始终期望它负责的每个人。


Promise.allSettled返回一个promise,该Promise.allSettled返回promise状态的快照数组来执行,但Promise.allSettled是必须解决所有原始的promise。


allSettled这个名字从哪里来?


我们说,如果未中止承诺即未兑现承诺,即 当他感到满意或被拒绝时-两件事之一。 要了解术语,请查看旧的《 国家和命运》文件。


而且,此名称allSettled广泛用于实现此功能的现有库中。 列表将在下面。


例子


假设您需要遍历一个promise数组并返回一个具有已知状态的新值(该值出现在逻辑的两个可能分支中的任何一个中)。


 function reflect(promise) { return promise.then( (v) => { return { status: 'fulfilled', value: v }; }, (error) => { return { status: 'rejected', reason: error }; } ); } const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.all(promises.map(reflect)); const successfulPromises = results.filter(p => p.status === 'fulfilled'); 

提出的API使开发人员可以处理这些选项,而无需独立创建reflect函数或将结果存储在临时变量中。 新的API如下所示:


 const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.allSettled(promises); const successfulPromises = results.filter(p => p.status === 'fulfilled'); 

如果由于某种原因我们需要拒绝承诺,那么可能我们需要收集发生情况的原因。 allSettled使此allSettled变得简单。


 const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.allSettled(promises); const errors = results .filter(p => p.status === 'rejected') .map(p => p.reason); 

真实的例子


非常希望知道所有请求均已完成,而不管每个请求的状态如何。 当您希望将来逐步改进时,这一点很重要。 我们并不总是需要从API获得响应。


 const urls = [ /* ... */ ]; const requests = urls.map(x => fetch(x)); // , -    ,  - - . //        ,   . try { await Promise.all(requests); console.log('  ,    .'); } catch { console.log('-    ,     . .'); } 

使用Promise.allSettled您可以编写更符合我们期望的内容。


 //   ,     API  . Promise.allSettled(requests).finally(() => { console.log('  :    ,   '); removeLoadingIndicator(); }); 

定制实施



用其他语言


其他语言也以不同的名称存在类似的功能。 由于没有可以立即与多种语言兼容的通用机制,因此本文档遵循上面列出的库中的名称示例。 其他语言的外观如下:


  • futures::join ;
  • C# Task.WhenAll 。 您可以使用try / catch或TaskContinuationOptions.OnlyOnFaulted ;
  • asyncio.wait使用ALL_COMPLETED选项的ALL_COMPLETED
  • Java- CompletableFuture.allOf

进一步研究的材料



TC39会议纪要



规格书



实作


Source: https://habr.com/ru/post/zh-CN459970/


All Articles