Spec-Zone.ru › Web APIs

Передаёмные объекты

Передаёмные объекты — это объекты, которые владеют ресурсами, которые могут быть переданы из одного контекста в другой, гарантируя, что ресурсы доступны только в одном контексте за раз. После передачи исходный объект больше не используется; он больше не указывает на переданный ресурс, и любая попытка чтения или записи объекта сгенерирует исключение.

Передаёмные объекты обычно используются для совместного использования ресурсов, которые могут быть безопасно предоставлены только одному потоку JavaScript за раз. Например, ArrayBuffer является передаваемым объектом, который владеет блоком памяти. Когда такой буфер передаётся между потоками, ассоциированный ресурс памяти отсоединяется от исходного буфера и присоединяется к объекту буфера, созданному в новом потоке. Объект буфера в исходном потоке больше не может быть использован, потому что он больше не владеет ресурсом памяти.

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

Для postMessage() и structuredClone(), переданные ресурсы должны быть присоединены к объекту данных, иначе они не будут доступны на стороне приёма, потому что передаваемый массив только указывает, как должны быть отправлены определённые ресурсы, но фактически не отправляет их (хотя они всегда будут отсоединены).

Механизм передачи ресурсов объекта зависит от объекта. Например, при передаче ArrayBuffer между потоками ресурс памяти, на который он указывает, буквально перемещается между контекстами в быстрой и эффективной операции без копирования. Другие объекты могут передаваться путём копирования ассоциированного ресурса, а затем его удаления из старого контекста.

Не все объекты передаваемы. Список передаваемых объектов представлен ниже.

Передача объектов между потоками

Код ниже демонстрирует, как работает передача при отправке сообщения из основного потока в поток веб-работы. Uint8Array копируется (дублируется) в рабочем потоке, в то время как его буфер передаётся. После передачи любая попытка чтения или записи uInt8Array из основного потока сгенерирует исключение, но вы по-прежнему можете проверить byteLength чтобы подтвердить, что он теперь равен нулю.

// Create an 8MB "file" and fill it. 8MB = 1024 * 1024 * 8 B
const uInt8Array = new Uint8Array(1024 * 1024 * 8).map((v, i) => i);
console.log(uInt8Array.byteLength); // 8388608

// Transfer the underlying buffer to a worker
worker.postMessage(uInt8Array, [uInt8Array.buffer]);
console.log(uInt8Array.byteLength); // 0

Примечание: Массивы с типом данных, такие как Int32Array и Uint8Array, являются сериализуемыми, но не передаваемыми. Однако их базовый буфер является ArrayBuffer, который является передаваемым объектом. Мы могли отправить uInt8Array.buffer в параметре данных, но не uInt8Array в массиве передачи.

Передача при операции клонирования

Код ниже демонстрирует операцию structuredClone(), где базовый буфер копируется из исходного объекта в клон.

const original = new Uint8Array(1024);
const clone = structuredClone(original);
console.log(original.byteLength); // 1024
console.log(clone.byteLength); // 1024

original[0] = 1;
console.log(clone[0]); // 0

// Transferring the Uint8Array would throw an exception as it is not a transferable object
// const transferred = structuredClone(original, {transfer: [original]});

// We can transfer Uint8Array.buffer.
const transferred = structuredClone(original, { transfer: [original.buffer] });
console.log(transferred.byteLength); // 1024
console.log(transferred[0]); // 1

// After transferring Uint8Array.buffer cannot be used.
console.log(original.byteLength); // 0

Поддерживаемые объекты

Интерфейсы, которые могут быть переданы, должны включать эту информацию в своём введении.

Ниже перечислены некоторые элементы, которые различные спецификации указывают как передаваемые (этот список может быть неполным!):

  • ArrayBuffer
  • MessagePort
  • ReadableStream
  • WritableStream
  • TransformStream
  • WebTransportReceiveStream
  • WebTransportSendStream
  • AudioData
  • ImageBitmap
  • VideoFrame
  • OffscreenCanvas
  • RTCDataChannel
  • MediaSourceHandle
  • MIDIAccess

Примечание: Передаваемые объекты отмечаются в файлах Web IDL атрибутом [Transferable]. Поддержка браузером может быть указана в соответствующей информации о совместимости объекта, используя подфункцию transferable (см. RTCDataChannel для примера).

См. также

  • Передаваемые объекты: молниеносная скорость!
  • Использование веб-работников
  • Передаваемые объекты в спецификации HTML
  • DedicatedWorkerGlobalScope.postMessage()

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects

Spec-Zone.ru

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