Await Dictionary S3
中文标题:await 字典
- 阶段: Stage 3
- 状态: 进行中
- ECMAScript 版本: —
- 同步时间: 2026年8月26日
- English original · 官方仓库
该提案解决了按属性名等待多个 Promise 的效率问题,避免顺序瀑布和基于顺序的混淆。它引入了 Promise.allKeyed 和 Promise.allSettledKeyed 静态方法,接受一个 Promise 对象并返回一个具有相同键的对象,所有 Promise 并行解析。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
等待 Promise 字典
状态
阶段:3
推动者:
- Ashley Claymore (@acutmore)
- Jordan Harband (@ljharb)
- Chris de Almeida (@ctcpip)
- 待定:Rick Waldron (@rwaldron)
作者:
- Alexander J. Vincent (@ajvincent)
- Ashley Claymore (@acutmore)
动机
逐个属性使用 await 会产生瀑布效应,而不是并行运行请求:
Promise.all 有所帮助,但它基于顺序而不是名称,这可能导致混淆:
使用现有语法的解决方案可能冗长,并且会_污染_作用域中的变量数量:
此外,上述模式有未处理的 Promise 拒绝的风险。如果 await shapeRequest 抛出异常,那么没有处理程序附加到 colorRequest 或 massRequest 的 Promise 上——如果这两个之一拒绝,将导致未处理的 Promise 拒绝错误。在某些系统上,这会导致进程退出。
提议的解决方案
这有意遵循了 https://github.com/tc39/proposal-joint-iteration 的形式。
正如 Promise.all 之于 Iterator.zip
Promise.allKeyed 之于 Iterator.zipKeyed
附加 API
本提案还将此特性扩展到了Promise.allSettled用户。
现有解决方案
实现
Polyfill/转译器实现
无。
原生实现
无。
问答
为什么没有深拷贝选项?
除了 JSON.stringify,内置的 JavaScript API 不常见地深度遍历任意对象。
Array.prototype.flat 是_深度的_,但仅限于明确定义的数组边界。
为什么只处理自有属性?
这遵循了其他内置函数,如 Object.keys,并且也与 https://github.com/tc39/proposal-joint-iteration 一致。
符号键呢?
所有可枚举属性都会被使用,包括可枚举的符号。
这与 https://github.com/tc39/proposal-joint-iteration 一致。
这与现有解决方案不同,后者遵循 Object.keys 的语义(忽略符号)。由于自有的可枚举符号使用频率较低,因此这种差异不构成问题。
考虑的替代方案
Promise.ownProperties
Promise.fromEntries
Promise.all 重载
根据参数是否为可迭代对象进行分派。
“这_确实_避免了在 API 表面引入新名称。然而,对于输出的形状依赖于输入的形状,以及意外传递多个参数而不是数组的风险,存在不适感。例如:
虽然目前这会因为 p1 不可迭代而抛出异常,但重载将开始允许这种调用,但不会执行调用者想要的意图。
专用语法
受其他语言(如 Swift)的启发 - 见:https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency#Calling-Asynchronous-Functions-in-Parallel
在 await <exp> 中对 async const 标识符的所有引用都会被隐式等待。
上述代码大致等价于: