Mass Proxy Revocation S1
中文标题:批量代理撤销
- 阶段: Stage 1
- 状态: 进行中
- ECMAScript 版本: —
- 同步时间: 2026年8月26日
- English original · 官方仓库
该提案解决了膜中一次性撤销大量代理的挑战,目前需要为每个代理显式创建 revoker 函数。它向 Proxy 和 Proxy.revocable 引入第三个参数以传递“信号”符号,并提供 Proxy.createSignal 和 Proxy.finalizeSignal 来管理撤销组。
以下 README 来自上游仓库,其中的阶段或状态标注可能滞后;当前信息以提案概览为准。
批量代理撤销
状态
- 冠军:Mark S. Miller, Jack Works(所有功劳归功于 Alex 和 Bradley)
- 作者:Alexander J. Vincent
- 荣誉作者:Bradley Farias
- 阶段:1
动机
膜(Membrane),使用 Proxy 和 WeakMap 将一个对象图(可以认为是“Realm”)与其他对象图分离,每个对象图中可能有成百上千个代理。在撤销一个对象图时,膜必须一次性撤销所有这些代理,以及在其他对象图中指向该对象图内对象的代理。
我们建议创建和跟踪“撤销信号”符号(symbols),开发者可以通过第三个参数将其实例传递给 new Proxy() 或 Proxy.revocable()。用户可以通过 Proxy.createSignal() 静态函数创建这些信号,并通过 Proxy.finalizeSignal(signal) 静态函数撤销它们。(我们知道取消(Cancellation)提案,并且非常愿意用该提案的 API 替换此机制。)
在 TypeScript 中(从 Microsoft 的 TypeScript 项目复制,遵循 Apache 许可证),这将如下所示:
示例:
使用场景
膜撤销整个对象图
考虑下面的情景,其中每个平面是一个 Realm,原始对象是球体,代理是半球体,垂直圆柱表示代理与其对象之间的连接。(这是膜的几何模型。)
图 1

如果我们想要撤销对黄色 Realm 的访问,我们不能仅撤销黄色 Realm 中的代理。蓝色和绿色 Realm 中的“onload”代理只有在尝试访问黄色“onload”对象并抛出异常时才会发现。它们已经死了但不知道。客户端代码负责处理这些异常。
注意,这里我们不指定膜的 API。膜的方法仅用于说明。
这样做的一个特别好处是将撤销管理(以及代理的垃圾回收)交还给 JavaScript 引擎。显式生成 revoker 函数的需求变得多余,但为了向后兼容,我们会保留它。
内存优化
如果我们不为每个代理实际创建 revoker 函数,这意味着更少的内存分配和更少的垃圾回收压力。
描述
面向开发者的功能使用文档
比较
对各种相关编程语言和/或库的比较。如果这是第一个做这种事情的语言或库,请解释原因。如果这是一个标准库特性,与 JavaScript 生态系统的比较会很好;如果这是一个语法特性,那可能不实际,比较可能仅限于其他编程语言。
有关于跨 Realm 传递 AbortSignals 的先例。参见 issue #1。
实现
Polyfill/transpiler 实现
该提案的 JavaScript 实现,理想情况下以方便、真实实验的方式打包。参见 implement.md 了解创建有用原型实现的细节。
原生实现
问答
常见问题,或你认为可能被问到的问题。问题跟踪器上的 issue 或过去审查中的问题可能成为这些问题的来源。
问:为什么这需要内置,而不是用 JavaScript 实现?
答:(1)我们希望将代理的实际管理交还给 JavaScript 引擎。膜存储数百个 revoker 然后同步撤销它们是痛苦的。(2)我们认为这种设计对 compartment 更有效。
问:为什么要有第三个参数?
答:我们认为这是保持向后兼容并添加我们请求的功能的最简单方法。我们也意识到正确塑造这第三个参数 API 的重要性。
问:这与取消(Cancellation)提案和/或 AbortController有什么关系?(#13)
答:我们当然愿意调整我们的提案,使之与取消提案兼容和/或依赖它。关于 AbortController,SES 认为让 TC39 提案依赖 Web API 是不可行的,除非 AbortController 成为 ECMAScript 的一部分(极不可能)。
特别是,Proxy.createSignal() 和 Proxy.finalizeSignal(signal) 方法我们可以用 TC39 的其他标准 API 替换。
超出范围
观察撤销
本提案旨在允许创建可撤销的代理分组。一般的信号机制一直是 TC39 讨论的主题,我们认为本提案无需观察机制即可达到目的。没有明确理由说明为什么不能在此处提出的 API 中添加信号作为后续功能。添加信号会带来各种问题,如重入性和与其他宿主环境特性的兼容性。