JavaScript PostMessage и несколько передаваемых объектов - PullRequest
0 голосов
/ 13 июня 2018

Я пытаюсь использовать экспериментальную функцию Canvas - offscreenCanvas.

index.html

<html>
  <body>
    <canvas id="myCanvas" width="400" height="400"></canvas>
  </body>

  <script>
    const canvas = document.querySelector('#myCanvas');
    const offscreenCanvas = canvas.transferControlToOffscreen();

    const worker = new Worker('./worker.js');
    worker.postMessage({offscreenCanvas}, [offscreenCanvas]);

  </script>
</html>


worker.js

onmessage = e => {
  const ctx = e.data.offscreenCanvas.getContext('2d');

  ctx.fillRect(0 , 0, 100 , 100);
  ctx.commit();
}

Здесь все работает нормально, я рисую простой прямоугольник на холсте.Теперь - как передать дополнительную информацию с помощью postMessage?Например - возможно ли отправить объект с прямоугольными координатами?

Как

const obj = {
  x: 0,
  y: 0,
}

Я пытался использовать переносимые объекты, создав новый Int8Array:

const bufferObj = new Int8Array([obj.x, obj.y]);

Toчестно говоря, я не знаю, как отправить его работнику и прочитать его с объекта события.Я думал о

worker.postMessage(offscreenCanvas, bufferObj, [offscreenCanvas, bufferObj]);

Но это выдает ошибку. Значение по индексу 1 не имеет переносимого типа.Есть идеи, как это решить?

1 Ответ

0 голосов
/ 13 июня 2018

Во-первых, если вам не нужно передавать право собственности на объект, а просто отправить его работнику, вы можете сделать это:

const obj = {
  x: 0,
  y: 0,
}

worker.postMessage({offscreenCanvas, obj}, [offscreenCanvas]);

И затем простодоступ с рабочего на e.data.obj без проблем.Для простого объекта я бы сказал, что это не главная проблема, поскольку postMessage использует алгоритм структурированного клона

Однако, если вам нужна оптимизация, и вы передаете большой объем данных - какoffscreen canvas - вы хотите вместо этого перенести объект на другую сторону.

В этом случае ваша ошибка заключалась в использовании Typed Array, который не реализует интерфейс Transferable.Вместо этого вы должны пройти ArrayBuffer.Например:

const buff = new Uint8Array([obj.x, obj.y]).buffer;

worker.postMessage({offscreenCanvas, buff}, [offscreenCanvas, buff]);

Это должно работать.

...