Spec-Zone.ru › JavaScript

DisposableStack.prototype.move()

Базовый уровень Ограниченная доступность

Эта функция не является Базовым уровнем, потому что она не работает в некоторых из наиболее широко используемых браузеров.

Метод move() экземпляров DisposableStack создаёт новый экземпляр DisposableStack, который содержит те же деструкторы, что и этот стек, а затем помечает этот стек как утилизированный, не вызывая при этом ни одного деструктора.

Синтаксис

move()

Параметры

Нет.

Возвращаемое значение

Новый экземпляр DisposableStack.

Исключения

ReferenceError
Выбрасывается, если стек уже утилизирован.

Описание

Основное назначение move() — обеспечить передачу ответственности за утилизацию за пределы текущей области видимости. Например, ваша функция может взять на себя владение некоторыми ресурсами и утилизировать их, если произойдёт ошибка; если всё завершится успешно, вы возвращаете эти ресурсы и передаёте владение вызывающей стороне.

При использовании move() для передачи владения вызов move() должен быть самым последним шагом в вашем потоке управления, поскольку не будет владельца между моментом, когда ваш код отказывается от владения через move(), и моментом, когда вызывающая сторона получает владение из возвращаемого значения.

let resource1;

function init() {
  using disposer = new DisposableStack();
  resource1 = disposer.use(getResource1());
  // ...
  // Drop ownership immediately before returning
  return disposer.move();
}

// Pick up ownership immediately after returning
using disposer = init();
let resource1;

function init() {
  using disposer = new DisposableStack();
  resource1 = disposer.use(getResource1());
  // ...
  const newDisposer = disposer.move();
  // If someone adds code in between these lines and an error occurs,
  // there would be no owner to free resource1
  return newDisposer;
}

using disposer = init();

Также будьте осторожны со следующим шаблоном, хотя использование «хорошего» шаблона может быть очень неудобным во многих случаях:

function init() {
  using disposer = new DisposableStack();
  const resource1 = disposer.use(getResource1());
  // ...
  return { disposer: disposer.move(), resource1 };
}

const { resource1, ...rest } = init();
// If someone adds code in between these lines and an error occurs,
// there would be no owner to free resource1
using disposer = rest.disposer;

move() также можно использовать для условной утилизации в случаях, когда вы иногда можете вообще не захотеть утилизировать ресурсы. Например:

using disposer = new DisposableStack();
const server = disposer.use(makeServer());
await server.init();
if (server.ready) {
  // Successfully initialized server; it now should live through the rest
  // of the program. Drop its disposer and don't pick it up. It will no
  // longer be disposed at all.
  disposer.move();
}
// If we reach the end of the scope without running disposer.move(),
// then server isn't ready for any reason, and we dispose its resources
// by disposing the disposer.

Примеры

Захват владения стеком

function consumeStack(stack) {
  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 DisposableStack();
console.log(stack.disposed); // false
consumeStack(stack);
console.log(stack.disposed); // true

Разрешение утилизации ресурсов в двух ветвях кода

Основной вариант использования move() — это когда у вас есть один или несколько ресурсов, которые могут быть либо утилизированы прямо здесь, либо сохранены для последующего использования. В этом случае вы можете поместить ресурсы в DisposableStack, а затем вызвать move(), когда вам потребуется сохранить ресурсы для последующего использования.

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

  constructor() {
    // Create a DisposableStack that is disposed when the constructor exits.
    // If construction succeeds, we move everything out of `disposer` and into
    // `#disposables` to be disposed later.
    using disposer = new DisposableStack();

    // Create an IPC adapter around process.send/process.on("message").
    // When disposed, it unsubscribes from process.on("message").
    this.#channel = disposer.use(new NodeProcessIpcChannelAdapter(process));

    // Create a pseudo-websocket that sends and receives messages over
    // a NodeJS IPC channel.
    this.#socket = disposer.use(new NodePluginHostIpcSocket(this.#channel));

    // If we made it here, then there were no errors during construction and
    // we can safely move the disposables out of `disposer` and into `#disposables`.
    this.#disposables = disposer.move();

    // If construction failed, then `disposer` would be disposed before reaching
    // the line above. Event handlers would be removed, allowing `#channel` and
    // `#socket` to be GC'd.
  }

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

    // NOTE: we can free `#socket` and `#channel` here since they will be
    // disposed by the call to `disposables[Symbol.dispose]()`, 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 Async Explicit Resource Management
# sec-disposablestack.prototype.move

Совместимость с браузерами

Настольные Мобильные Серверные
Chrome Edge Firefox Opera Safari Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet WebView Android WebView on iOS Bun Deno Node.js
move
134
134
141
119
preview
134
141
88
Нет
29.0
134
Нет
1.3.0
2.2.10
24.0.0

Смотрите также

  • Управление ресурсами JavaScript
  • DisposableStack
  • DisposableStack.prototype.dispose()

© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DisposableStack/move

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API