Promise.all([])返回已解决的promise,但Promise.race([])返回一个挂起的promise。他们为什么不同?

时间:2018-04-16 04:28:23

标签: javascript promise es6-promise

如果使用非空数组调用Promise.all或Promise.race,它们将返回一个待处理的承诺:

console.log(Promise.all([1]));
// prints Promise {<pending>}
console.log(Promise.race([1]));
// returns Promise {<pending>}

如果使用空数组调用Promise.race,则返回一个待处理的promise:

console.log(Promise.race([]));
// prints Promise {<pending>}

但是如果用一个空数组调用Promise.all,它将返回一个已经解析的promise:

console.log(Promise.all([]));
// prints Promise {<resolved>: Array(0)}

为什么Promise.all功能设计得像这样?似乎没有充分理由不一致,但也许我错过了一些东西。

1 个答案:

答案 0 :(得分:2)

来自EMCA Script specification for Promise.race()

  

如果iterable参数为空或者iterable中的promise都没有解决,那么此方法返回的挂起的promise将永远不会被解决

Promise.all()规范在这方面并不是那么容易理解,但基本上当你传递一个空数组时,它开始时它们被称为remainingElementsCount {{1}这让它立即解决。

当您向0传递一个值时,可能会将该值包装在Promise.all([1])中,然后跟踪Promise.resolve()处理程序,该处理程序将在下一个时钟点解析.then() {1}}显示它在下一个刻度之前仍处于待处理状态。

从逻辑上讲,对此有一定道理。 console.log(Promise.all([1]))应该解析为第一个要解决的承诺的价值,但是如果你没有通过任何东西,那么确实没有第一个解决的价值。唯一的其他选择是拒绝或解析Promise.race()或抛出无效使用的例外。我不太确定为什么设计师会选择他们所做的结果而不是其他选择,但至少它在规范中有详细说明。

另一方面,

undefined可以很好地解析为空数组,这是传递空数组的合理结果。

  

为什么Promise.all功能设计得像这样?

真的&#34;知道&#34;设计师的逻辑,你不得不问其中一个或参与讨论或找到讨论逻辑的邮件列表讨论。

但是,人们可以提出一个论点,如果你有一个可变长度数组的东西,你想等待完成Promise.all()该函数应该工作,无论数组中有20个项目还是0。对于Promise.all()长度数组的情况,它只会在下一个tick上立即解析,这将既有用又一致,因为没有承诺可以等待并且有一个已解析的值(一个空数组)这符合并且是一致的。

ES6关于主题的讨论

这是指向0永不解决的发展讨论的链接:https://github.com/domenic/promises-unwrapping/issues/75。当然有人不同意目前的实施情况。

我的个人意见(在本主题的各种讨论中由其他人分享)是它应该抛出异常,因为它基本上是无效的条件,从开发的角度来看,快速失败,引人注目&#34;比无限的承诺要好得多。但是,显然有更多人喜欢它的方式。

Bluebird docs建议使用Promise.race()代替Promise.any(),部分原因是它没有此行为。

相关问题