Worker.postMessage()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

Метод postMessage() интерфейса Worker отправляет сообщение во внутреннее пространство worker-а. Метод имеет один параметр с данными для отправки в worker. Данные могут быть любым значением или объектом JavaScript, которые может обработать алгоритм структурированного клонирования, поддерживающий циклические ссылки.

Worker может отправить обратно информацию потоку создавшему его с помощью метода DedicatedWorkerGlobalScope.postMessage.

Синтаксис

js
worker.postMessage(message, [transfer]);

Параметры

message

Object передаваемый в worker. Будет содержаться в поле data описания события обработчика DedicatedWorkerGlobalScope.onmessage. Это может быть любое значение или объект JavaScript, которые может обработать алгоритм структурированного клонирования, поддерживающий циклические ссылки.

transfer Необязательный

Необязательный array с передаваемыми (Transferable) объектами (из тех, что были указаны в message) на которые передаются права собственности. Если право на объект передаётся, он становится непригодным (neutered) в контексте, из которого был отправлен, и становится доступным только в worker, которому он был отправлен.

Переданные (transferable) объекты могут быть экземплярами классов ArrayBuffer, MessagePort или ImageBitmap. null не является допустимым значением для передачи прав.

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

Void.

Пример

В следующем фрагменте кода показано создание объекта Worker с помощью конструктора Worker(). При изменении значений одного из двух полей формы (first и second) событием change вызывается функция postMessage() для отправки значений полей текущему worker.

js
var myWorker = new Worker("worker.js");

first.onchange = function () {
  myWorker.postMessage([first.value, second.value]);
  console.log("Сообщение отправлено работнику");
};

second.onchange = function () {
  myWorker.postMessage([first.value, second.value]);
  console.log("Сообщение отправлено работнику");
};

Больше примеров можно найти здесь: Basic dedicated worker example (run dedicated worker).

Примечание: postMessage() может отправить только один объект за раз. Если нужно передать несколько значений, то можно отправить массив, как показано выше.

Пример с Transfer

В этом примере показано дополнение Firefox, которое передаёт ArrayBuffer из основного потока в ChromeWorker, а затем ChromeWorker передаёт его обратно в основной поток.

Код основного потока

js
var myWorker = new ChromeWorker(self.path + "myWorker.js");

function handleMessageFromWorker(msg) {
  console.log("входящее сообщение от работника:", msg);
  switch (msg.data.aTopic) {
    case "do_sendMainArrBuff":
      sendMainArrBuff(msg.data.aBuf);
      break;
    default:
      throw "свойство aTopic отсутствует в сообщении ChromeWorker";
  }
}

myWorker.addEventListener("message", handleMessageFromWorker);

// Создание и отправка буфера
var arrBuf = new ArrayBuffer(8);
console.info("arrBuf.byteLength, ДО передачи:", arrBuf.byteLength);

myWorker.postMessage(
  {
    aTopic: "do_sendWorkerArrBuff",
    aBuf: arrBuf, // буфер который передаётся 3 строками ниже
  },
  [
    arrBuf, // буфер созданный на строке 9
  ],
);

console.info("arrBuf.byteLength, ПОСЛЕ передачи:", arrBuf.byteLength);

Код Worker-а

js
self.onmessage = function (msg) {
  switch (msg.data.aTopic) {
    case "do_sendWorkerArrBuff":
      sendWorkerArrBuff(msg.data.aBuf);
      break;
    default:
      throw "свойство aTopic отсутствует в сообщении ChromeWorker";
  }
};

function sendWorkerArrBuff(aBuf) {
  console.info(
    "от рабочего, ДО отправки обратно, aBuf.byteLength:",
    aBuf.byteLength,
  );

  self.postMessage({ aTopic: "do_sendMainArrBuff", aBuf: aBuf }, [aBuf]);

  console.info(
    "от рабочего, ПОСЛЕ отправки обратно, aBuf.byteLength:",
    aBuf.byteLength,
  );
}

Лог консоли

arrBuf.byteLength, ДО передачи: 8                               bootstrap.js:40
arrBuf.byteLength, ПОСЛЕ передачи: 0                            bootstrap.js:42

от рабочего, ДО отправки обратно, aBuf.byteLength: 8            myWorker.js:5:2

входящее сообщение от работника: message { ... }                bootstrap.js:20
буфер вернулся в основной поток, aBuf.byteLength: 8             bootstrap.js:12

от рабочего, ПОСЛЕ отправки обратно, aBuf.byteLength: 0         myWorker.js:7:2

byteLength равен 0 потому, что это переданный (transferable) объект. Полный пример демо дополнения Firefox можно найти здесь: GitHub :: ChromeWorker - demo-transfer-arraybuffer

Спецификации

Specification
HTML
# dom-worker-postmessage-dev

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

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
postMessage
options.includeUserActivation parameter
Non-standard

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
Partial support
Partial support
No support
No support
Non-standard. Check cross-browser support before using.
See implementation notes.
Has more compatibility info.

[1] Internet Explorer не поддерживает Transferable объекты.

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