是否有可能将转移的ArrayBuffer返回原始类型的数组?

时间:2013-12-23 07:25:23

标签: javascript multithreading web-worker

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

main.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的所有权。我误会了什么吗?有没有办法实现这个目标?

非常感谢任何建议。

1 个答案:

答案 0 :(得分:2)

不,它没有那样的工作。 Int16Array只是一个包裹ArrayBuffer的接口,这是存储真实二进制数据的地方。转移所有权时,Int16Array无效(设置为0长度)。在您的工作人员中,会创建新的Int16Array并将其分配给旧的ArrayBuffer。我为您打造了这张图片:

image description

  1. 发布消息从已键入的数组中删除缓冲区。
  2. 所有不可转移的内容(即ArrayBuffer)被序列化为Structured clone,数组缓冲区被转移
  3. Int16Array对象不再是缓冲区,因此无效
  4. 结构化克隆被反序列化并创建新的Int16Array实例,此实例接收传输的ArrayBuffer
  5. 显然,解释器无法知道您返回ArrayBuffer,因此输入的数组永远无效。