AsyncDisposableStack.prototype.move()

可用性有限

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

move() 方法是 AsyncDisposableStack 实例的方法,它会创建一个新的 AsyncDisposableStack 实例,该实例包含与当前堆栈相同的处置器,然后将当前堆栈标记为已处置,而不会调用任何处置器。

语法

js
move()

参数

无。

返回值

一个新的 AsyncDisposableStack 实例。

异常

ReferenceError

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

示例

声明对堆栈的所有权

js
async function consumeStack(stack) {
  await using newStack = stack.move(); // newStack now owns the disposers
  console.log(stack.disposed); // true
  console.log(newStack.disposed); // false
  // newStack is disposed here immediately before the function exits
}

const stack = new AsyncDisposableStack();
console.log(stack.disposed); // false
await consumeStack(stack);
console.log(stack.disposed); // true

允许在两个代码路径中处置资源

move() 的主要用例是当你有一个或多个资源,这些资源可以立即在此处处置,也可以保留以供将来使用。在这种情况下,你可以将这些资源放入 AsyncDisposableStack 中,然后在需要保留这些资源以供将来使用时调用 move()

js
class PluginHost {
  #disposed = false;
  #disposables;
  #channel;
  #socket;

  static async init() {
    // Create a AsyncDisposableStack that is disposed when init exits.
    // If construction succeeds, we move everything out of `stack` and into
    // `#disposables` to be disposed later.
    await using stack = new AsyncDisposableStack();

    const channel = stack.use(await getChannel());

    const socket = stack.use(await getSocket());

    // If we made it here, then there were no errors during construction and
    // we can safely move the disposables out of `stack`.
    return new PluginHost(channel, socket, stack.move());

    // If construction failed, then `stack` would be disposed before reaching
    // the line above, which would dispose `channel` and `socket` in turn.
  }

  constructor(channel, socket, disposables) {
    this.#channel = channel;
    this.#socket = socket;
    this.#disposables = disposables;
  }

  [Symbol.asyncDispose]() {
    if (this.#disposed) {
      return;
    }
    this.#disposed = true;
    // Put `this.#disposables` into a `using` variable, so it is automatically
    // disposed when the function exits.
    await using disposables = this.#disposables;

    // NOTE: we can free `#socket` and `#channel` here since they will be
    // disposed by the call to `disposables[Symbol.asyncDispose]()`, below.
    // This isn't strictly a requirement for every disposable, but is
    // good housekeeping since these objects will no longer be useable.
    this.#socket = undefined;
    this.#channel = undefined;
    this.#disposables = undefined;
  }
}

规范

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

浏览器兼容性

另见