【问题标题】:Promise.all([]) returns a resolved promise, but Promise.race([]) returns a pending promise. Why are they different?Promise.all([]) 返回一个已解决的 Promise,但 Promise.race([]) 返回一个待处理的 Promise。为什么它们不同?
【发布时间】:2018-09-25 17:49:31
【问题描述】:

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

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 函数?似乎没有充分的理由导致不一致,但也许我遗漏了一些东西。

【问题讨论】:

  • 它在文档(竞赛)中定义:“如果传递的可迭代对象为空,则返回的承诺将永远挂起。” Promise.all 文档:“如果传递了一个空的可迭代对象,则此方法(同步)返回一个已解决的承诺。”
  • 是有道理的,因为一切都什么都不是,但永远无法确定先入为主
  • 您是否有任何具体原因希望.all.race 一样工作……反之亦然?
  • 不,我只是想更深入地了解 Promise,令我感到奇怪的是 when.all([]) 返回一个已经解决的 Promise(而不是在下一个解决打钩)。我想知道我是否遗漏了一些潜在的概念。

标签: javascript promise es6-promise


【解决方案1】:

来自EMCA Script specification for Promise.race()

如果 iterable 参数为空,或者如果 iterable 中的任何 promise 都没有解决,则此方法返回的待处理 promise 将永远不会被解决


Promise.all() 规范在这方面并不是那么容易遵循,但基本上当你传递一个空数组时,它会从他们所指的 remainingElementsCount0 开始,它可以解决马上。

当您向它传递Promise.all([1]) 中的值时,它可能会将该值包装在Promise.resolve() 中,然后跟踪.then() 处理程序,该处理程序将在下一个滴答时解析,因此console.log(Promise.all([1])) 显示它仍在等待处理在下一个刻度之前。


从逻辑上讲,这是有道理的。 Promise.race() 应该解析为第一个要解析的承诺的值,但如果你什么都不传递,那么真的没有第一个解析的值。唯一的其他选择是拒绝或解析为undefined 或为无效使用抛出异常。我不太清楚为什么设计师选择他们所做的结果而不是其他选择,但至少在规范中明确详细说明。

另一方面,Promise.all() 可以很好地解析为空数组,这是传递空数组的逻辑结果。

为什么要这样设计 Promise.all 函数?

要真正“了解”设计者的逻辑,您必须询问其中一位,或者参加过讨论,或者找到讨论逻辑的邮件列表讨论。

但是,可以提出一个论点,即如果你有一个可变长度的数组,你想用Promise.all() 等待完成,那么无论数组中有 20 项还是 0 项,该函数都应该工作。在这种情况下对于0 长度数组,它只会在下一个滴答时立即解析,这既有用又一致,因为没有等待的承诺,并且有一个适合且一致的解析值(一个空数组)。


ES6 主题讨论

这里是Promise.race() 从未解决的开发讨论的链接:https://github.com/domenic/promises-unwrapping/issues/75。肯定有人不同意当前的实施。

我的个人观点(在这个主题的各种讨论中被其他人分享)是它应该抛出一个异常,因为它基本上是一个无效的条件,从开发的角度来看,“快速失败和明显”比无限的承诺。但是,显然有更多的人喜欢它。

Bluebird docs 推荐使用他们的Promise.any() 而不是Promise.race(),部分原因是它没有这种行为。

【讨论】:

    猜你喜欢
    • 2020-08-06
    • 1970-01-01
    • 2022-10-05
    • 1970-01-01
    • 2017-10-24
    • 2021-08-23
    • 2017-02-10
    • 2020-07-18
    • 2021-09-10
    相关资源
    最近更新 更多