0Pricing
JavaScript Academy · Урок

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

Перемещайте данные эффективно, не создавая копий.

«Передаваемые объекты» — бесплатный урок JavaScript Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения JavaScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс JavaScript Academy содержит 4 уроков всего.

Цена клонирования

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

Что можно передавать

Передавать можно только определённые типы объектов, и важнейший из них — ArrayBuffer. К ним также относятся MessagePort, ImageBitmap и OffscreenCanvas.

  • ArrayBuffer — необработанная двоичная память
  • MessagePort — конечная точка канала
  • ImageBitmap — декодированные данные изображения

Список передачи

postMessage принимает второй аргумент — список передаваемых объектов. Объекты из этого списка перемещаются, а не копируются.

const buffer = new ArrayBuffer(1024 * 1024); // 1 MB
worker.postMessage(buffer, [buffer]); // transfer it

Перемещение владения

После передачи отправляющая сторона больше не может использовать buffer: он становится отсоединённым (byteLength 0). Теперь принимающая сторона владеет той же базовой памятью, и копирование не выполняется.

const buffer = new ArrayBuffer(8);
worker.postMessage(buffer, [buffer]);
console.log(buffer.byteLength); // 0 - now detached

Передача типизированных массивов

Передавайте лежащий в основе типизированного массива ArrayBuffer через его свойство .buffer. Само представление передавать нельзя, но его buffer — можно.

const data = new Float64Array(100000);
worker.postMessage(data, [data.buffer]);
// data is now detached on this side.

Получение переданного объекта

Принимающая сторона читает переданный объект из event.data точно так же, как клонированное сообщение. Разница лишь в том, что копирование не выполнялось.

// worker.js
self.onmessage = (e) => {
  const buffer = e.data; // we now own this memory
  const view = new Uint8Array(buffer);
  view[0] = 255;
};

Отправка результатов обратно

После обработки worker может передать buffer обратно, снова без копирования, вернув владение основному потоку.

// worker.js
self.onmessage = (e) => {
  const buffer = e.data;
  // ...process the bytes...
  self.postMessage(buffer, [buffer]); // transfer back
};

Производительность передачи и клонирования

Для нескольких килобайт разница незначительна. Для мегабайт двоичных данных передача значительно быстрее и позволяет избежать резкого скачка использования памяти. Используйте её для больших объектов buffer.

Как избежать ошибок использования после передачи

Распространённая ошибка — чтение buffer после его передачи. Всегда считайте buffer недоступным, как только он появляется в списке передачи.

worker.postMessage(buffer, [buffer]);
// BUG: buffer is detached here; this reads zero length.
// const len = buffer.byteLength; // 0

Сочетание клонированных и переданных данных

Можно отправить объект, содержащий buffer, и передать только этот buffer. Объект клонируется, а указанный buffer перемещается.

const msg = { type: 'frame', pixels: buffer };
worker.postMessage(msg, [buffer]);
// msg.type is cloned; buffer is transferred.

Когда использовать передачу

Используйте передаваемые объекты для обработки изображений, аудио и видео, больших числовых вычислений и любого конвейера, перемещающего большие двоичные блоки между потоками. Для небольших данных в формате JSON обычное клонирование проще и вполне подходит.

Проверка знаний

Проверьте, насколько хорошо Вы поняли передаваемые объекты.

Повторение

Вы изучили передаваемые объекты:

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

Далее Вы изучите варианты применения и ограничения worker.

Часто задаваемые вопросы

Урок «Передаваемые объекты» бесплатный?

Да — полный текст урока «Передаваемые объекты» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс JavaScript Academy, подпишись на CoddyKit PRO. Курс JavaScript Academy содержит 4 уроков всего.

Чему я научусь в уроке «Передаваемые объекты»?

Перемещайте данные эффективно, не создавая копий. Ты практикуешь JavaScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать JavaScript Academy?

Предыдущий опыт не требуется. JavaScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Передаваемые объекты»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке JavaScript Academy?

Да. Каждый урок JavaScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Создание Web Worker
  2. Обмен сообщениями с postMessage
  3. Передаваемые объекты
  4. Сценарии применения и ограничения
← Назад к JavaScript Academy