JavaScript postMessage 和多个可传输对象

标签 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();
}

这里一切正常,我在 Canvas 上绘制了简单的矩形。现在 - 如何使用 postMessage 传递附加信息?例如 - 是否可以发送具有矩形坐标的对象?

喜欢

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

我尝试通过创建新的 Int8Array 来使用可转移对象:

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

老实说,我不知道如何将它发送给工作人员并从事件对象中读取它。我在想

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

但是这会抛出错误 Value at index 1 does not have a transferable type。知道如何解决这个问题吗?

最佳答案

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

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

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

然后从 worker 访问 e.data.obj 没有问题。对于简单的对象,我认为这不是主要问题,因为 postMessage 使用 Structured clone algorithm

但是,如果您需要优化,并且传递了大量数据(作为屏幕外 Canvas ),您希望将对象转移到另一侧。

在这种情况下,您的错误是使用了未实现 Transferable 接口(interface)的 Typed Array。相反,您必须传递 ArrayBuffer。例如:

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

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

那应该行得通。

关于JavaScript postMessage 和多个可传输对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50840096/

相关文章:

javascript - 编辑后保存捕获的屏幕截图

java - 无法在处理程序方法之外访问 Canvas 元素

javascript - 当我尝试缓存 xxx.worker.js 时,Service Worker 不会安装

javascript - 结合 Processing.js 和 Web Worker 的强大功能

javascript - 向具有特定类别的每隔一个项目添加一个类别

Javascript 复杂类

javascript - HTML5 Canvas ImageData 不正确的 rgb 值

javascript - asp.net mvc serialize() 在 Controller 的模型中返回空

javascript - Javascript 中奇怪的迭代变量作用域

javascript - Web-Worker中同步等待消息