如果使用非空数组调用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功能设计得像这样?似乎没有充分理由不一致,但也许我错过了一些东西。
答案 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()
,部分原因是它没有此行为。