javascript 使用来自 Web Worker 的可传输对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16071211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using transferable objects from a Web Worker
提问by alt.126
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:
然后是webwork.js
Web Worker的代码:
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:
现在我想ArrayBuffer
用以下代码传输 128 兆字节:
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. 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.
现在我应该已经传输了变量r
,我如何从 Web Worker 本身访问它。我已经尝试过event.r
,只是r
,self.r
以及其他一些事情,比如尝试为 的数组添加第二个函数参数ArrayBuffers
,但没有任何效果。
How can I access the transferred variable(s) from the Web Worker?
如何从 Web Worker 访问传输的变量?
回答by yanni
The answer given by sbr works, but it would cause a copy of the data to be made before being sent to the worker. 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. 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:
sbr 给出的答案有效,但它会导致在发送给工作人员之前制作数据的副本。对于大量数据,这可能会很慢。
要使用“可转移对象”,您实际上是将对象的所有权转移到 Web Worker 或从 Web Worker 转移。这就像在没有复制的情况下通过引用传递。它与普通的传递引用的区别在于,传输数据的一侧无法再访问它。
我相信您应该在示例中发送数据的方式是:
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. 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):
在我自己的应用程序中,我需要从 web worker 向主线程发送一个大类型的 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.)
Also, if you want to send other information in addition to the large array, you can do this:
请注意,这在 Chrome 中有效,但截至目前可能不适用于大多数其他浏览器(尚未尝试)。
此外,如果您想发送除大数组之外的其他信息,您可以这样做:
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
// ...
});
回答by CoolCmd
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;
}
回答by Wyatt
回答by sbr
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.
}