DisposableStack.prototype.adopt()

可用性有限

此特性不是基线特性,因为它在一些最广泛使用的浏览器中不起作用。

adopt() 方法用于 DisposableStack 实例,通过提供自定义的清理函数来将未实现可处置协议的值注册到堆栈中。

语法

js
adopt(value, onDispose)

参数

value

要注册到堆栈的任何值。

onDispose

在堆栈被处置时将被调用的函数。该函数接收 value 作为其唯一参数。

返回值

传入的 value 相同。

异常

TypeError

如果 onDispose 不是函数,则抛出异常。

ReferenceError

如果堆栈已被处置,则抛出异常。

描述

adopt() 的主要目的是将未实现可处置协议的值注册到堆栈中。如果该值已实现可处置协议,您可以使用 use() 代替,它会自动使用该值的 [Symbol.dispose]() 方法作为清理函数。

adopt(value, onDispose) 几乎等同于 defer(() => onDispose(value)),但它允许您在同一行声明资源并进行注册。这样,在资源创建和注册之间发生错误的几率降到最低,从而避免资源泄露。

js
using disposer = new DisposableStack();
const reader = disposer.adopt(stream.getReader(), (reader) =>
  reader.releaseLock(),
);
js
using disposer = new DisposableStack();
const reader = stream.getReader();
// If someone adds code in between these lines and an error occurs,
// the stream will be locked forever.
disposer.defer(() => reader.close());

秉承“在声明资源时尽快注册它”的精神,您应该始终将资源获取表达式包装在 adopt() 中,而不是将其提取到单独的语句中。

js
using disposer = new DisposableStack();
const reader = stream.getReader();
disposer.adopt(reader, (reader) => reader.close());

示例

使用 adopt()

此代码通过 ReadableStreamDefaultReader 使用 ReadableStream。读取器未实现可处置协议,因此我们使用 adopt() 将其注册到堆栈。

js
{
  using disposer = new DisposableStack();
  const reader = disposer.adopt(stream.getReader(), (reader) =>
    reader.releaseLock(),
  );
  const { value, done } = reader.read();
  if (!done) {
    // Process the value
  }
  // The reader.releaseLock() method is called here before exiting
}

规范

规范
ECMAScript 异步显式资源管理
# sec-asyncdisposablestack.prototype.adopt

浏览器兼容性

另见