JavaScript postMessage和多个可转移对象

时间:2018-06-13 14:44:13

标签: javascript canvas web-worker postmessage

我正在尝试使用实验性的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]);

说实话,我不知道如何将它发送给worker并从事件对象中读取它。我在考虑

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

但这会引发错误索引1处的值没有可转移类型。知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

首先,如果您不需要转移对象的所有权,只需将其发送给工作人员,您就可以这样做:

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

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

然后只需从工作人员访问e.data.obj即可。对于简单的对象,我会说这不是一个主要问题,因为postMessage使用Structured clone algorithm

但是,如果您需要优化,并且传递大量数据(作为屏幕外画布),则需要在另一侧传输对象。

在这种情况下,您的错误是使用未实现Typed Array接口的Transferable。相反,您需要传递ArrayBuffer。例如:

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

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

这应该有效。