javascript - 是否可以将传输的 ArrayBuffer 返回原始类型数组?

标签 javascript multithreading web-worker

我知道将对象传输到 Web Worker 会导致主线程失去所有权。我想知道是否有任何方法可以让它重新获得所有权。这Plunker (下面的代码)演示了我遇到的问题。

ma​​in.js

var worker = new Worker("worker.js");
var z = new Int16Array(10);
worker.onmessage = function(e) {
    console.log(e.data);  // [0, 1, ... 10]
    console.log(z);  // [], ownership not regained here
}
console.log(z);  // [0, 0, ... 0], original value here
worker.postMessage(z, [z.buffer]);
console.log(z);  // [], ownership lost here

worker.js

self.onmessage = function(e) {
    var data = e.data;  // transferred "z" from main.js
    for (var i = 0; i < 10; i++) {
        data[i] = i;
    }
    // I thought this would return ownership back to the main thread
    self.postMessage(data, [data.buffer]);
}

从本质上讲,最终目标是从工作线程内更改主线程中的 z 的值,而不必在收到消息后将结果复制到主线程中。但是,z 的所有权似乎由 worker 保留。我误会了什么吗?有办法实现吗?

非常感谢任何建议。

最佳答案

不,它不是那样工作的。 Int16Array 只是一个包装在 ArrayBuffer 上的接口(interface),它是存储实际二进制数据的地方。当您转移所有权时,Int16Array 将失效(设置为 0 长度)。在您的 worker 中,新的 Int16Array 被创建并分配给旧的 ArrayBuffer。我为你制作了这张图片:

image description

  1. 发布消息从类型数组中删除缓冲区。
  2. 不可转移的所有内容(即 ArrayBuffer)都序列化为 Structured clone , 数组缓冲区被转移
  3. Int16Array 对象不再有缓冲区,因此无效
  4. 结构化克隆被反序列化并创建新的 Int16Array 实例,该实例接收传输的 ArrayBuffer

显然,解释器无法知道您返回了 ArrayBuffer,因此类型化数组永远无效。

关于javascript - 是否可以将传输的 ArrayBuffer 返回原始类型数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20738845/

相关文章:

javascript - 问题 "smartening"和链接解析相同的文本

java - 将简单的java对象从一个线程传递到另一个线程的快速方法

javascript - 停止 Canvas 动画 setInterval

java - 什么是java中的类级锁

java - 奇偶序列java 2线程

javascript - 使用 Emscripten Worker API 传输数据而不复制

javascript - 是否存在 Firefox Workers 限制?

javascript - 在 jsp 困境中保留 HTML 选择选项

javascript - 进行查询选择用户名并触发模式以隐藏 - Ajax 和 Jquery

javascript - 淡入淡出多个元素