[英]Using transferable objects from a Web Worker
I currently have this code to create a Web Worker:我目前有这个代码来创建一个 Web Worker:
w = new Worker("webwork.js");
w.onmessage = function(event) { alert(event.data); }
And then the webwork.js
code for the Web Worker:然后是 Web Worker 的
webwork.js
代码:
self.onmessage = function(event) {
//var ss=r; //Causes error because of undefined
var ss="";
for(var currProp in event) {
ss+=("event."+currProp+"="+event[currProp]+"\n");
}
postMessage(ss);
}
Now I want to transfer a 128-Megabyte ArrayBuffer
with this code:现在我想用这段代码传输一个 128 兆字节的
ArrayBuffer
:
var r = new ArrayBuffer(1048576*128);
w.postMessage(0, [r]);
Now that I have supposedly transferred the variable r
, how do I access it from the Web Worker itself.现在我应该已经转移了变量
r
,我如何从 Web Worker 本身访问它。 I have tried event.r
, just r
, self.r
and other things like trying to add a second function argument for the array of ArrayBuffers
, but nothing works. I have tried
event.r
, just r
, self.r
and other things like trying to add a second function argument for the array of ArrayBuffers
, but nothing works.
How can I access the transferred variable(s) from the Web Worker?如何从 Web Worker 访问传输的变量?
The answer given by sbr works, but it would cause a copy of the data to be made before being sent to the worker. sbr给出的答案有效,但它会在发送给工作人员之前生成数据的副本。 That could be slow for a large amount of data.
对于大量数据而言,这可能会很慢。
To use "transferable objects" you actually transfer the ownership of the object to or from the web worker. 要使用“可转移对象”,您实际上将对象的所有权转移到Web工作者或从Web工作者转移。 It's like passing by reference where a copy isn't made.
这就像通过引用传递没有复制的地方。 The difference between it and the normal pass-by-reference is that the side that transferred the data can no longer access it.
它与正常的引用传递之间的区别在于传输数据的一方无法再访问它。
I believe the way you should send the data in your example is: 我相信你应该在你的例子中发送数据的方式是:
w.postMessage(r,[r]); // first arg is r, not 0 as in the question
And the way you would access it in the web worker: 以及在Web worker中访问它的方式:
addEventListener('message', function(event) {
var r = event.data;
});
In my own application I needed to send a large typed Float64Array from the web worker to the main thread, without the performance penalty of the copy. 在我自己的应用程序中,我需要从Web worker向主线程发送一个大型的Float64Array,而不会对副本造成性能损失。 It took lots of trial and error and searching, so I figured I should include that example here for anyone else who gets stuck with a similar problem.
它需要大量的试验和错误以及搜索,因此我认为我应该将这个示例包含在其他任何遇到类似问题的人身上。
This is the code that worked on the worker side (arr is my Float64Array): 这是在工作者端工作的代码(arr是我的Float64Array):
self.postMessage(arr.buffer, [arr.buffer]);
On the receiving main thread I have: 在接收主线程上我有:
theWorker.addEventListener('message', function(ev) {
var arr = new Float64Array(ev.data); // just cast it to the desired type - no copy made
// ...
});
Note that this works in Chrome, but maybe not most other browsers as of this date (haven't tried yet.) 请注意,这适用于Chrome,但截至此日期可能不是大多数其他浏览器(尚未尝试过。)
Also, if you want to send other information in addition to the large array, you can do this: 此外,如果除了大型阵列之外还要发送其他信息,可以执行以下操作:
self.postMessage({foo:"foo", bar:arr.buffer}, [arr.buffer]);
On the receiving (in this example the main) thread: 在接收(在此示例中为主)线程:
theWorker.addEventListener('message', function(event) {
var foo = event.data.foo;
var arr = new Float64Array(event.data.bar); // cast it to the desired type
// ...
});
PostMesage(aMessage, transferList)
In transferList
you must specify transferable objects, which contained in aMessage
: 在
transferList
您必须指定包含在aMessage
转移对象:
var objData =
{
str: "string",
ab: new ArrayBuffer(100),
i8: new Int8Array(200)
};
objWorker.postMessage(objData, [objData.ab, objData.i8.buffer]);
On other side: 在另一边:
self.onmessage = function(objEvent)
{
var strText = objEvent.data.str;
var objTypedArray = objEvent.data.ab;
var objTypedArrayView = objEvent.data.i8;
}
this works for me : 这对我有用:
//in the Main //在主要
var x = new ArrayBuffer(1048576*128);
w.postMessage({buffer: x});
// In the worker thread, in message handler, //在工作线程中,在消息处理程序中,
processMessage: function(ev){
var buffer = ev.data.buffer,
// other stuff . buffer is referenced correctly here.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.