简体   繁体   English

使用 Web Worker 中的可转移对象

[英]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;
}

Try w.postMessage([0,r]). 尝试w.postMessage([0,r])。 To use transferable objects, one needs to pass the array buffer as the second item on an array. 要使用可传输对象,需要将数组缓冲区作为数组中的第二项传递。 See this 看到这个

if you want to use web worker easily, you can try this small lib : WW 如果你想轻松使用web worker,你可以试试这个小的lib: WW

hope it helps 希望能帮助到你

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.

相关问题 有没有一种方法可以将对象数组作为可转移对象传递给网络工作者? - Is there a way to pass an array of objects to a web worker as a transferable object? Web Workers - JSON的可转换对象 - Web Workers - Transferable Objects for JSON 如何通过 JavaScript - postMessage() 中的 web worker 传递可转移对象数组,即缓冲区以及不可转移的 object,即 json obj? - How to pass array of transferable objects i.e. buffer along with non transferable object i.e. json obj via web worker in JavaScript - postMessage()? Memory 泄漏:JavaScript - 使用可转移的 object 将数组缓冲区传递给 Web Worker,GC 不会启动 - Memory Leak: JavaScript - passing array buffer to Web Worker using transferable object, GC doesn't kick in Echartjs 中的 web worker 实现问题“无法在 'Worker' 上执行 'postMessage':索引 0 处的值没有可转移类型。” - Issues with web worker Implementation in Echartjs "Failed to execute 'postMessage' on 'Worker': Value at index 0 does not have a transferable type." 使用web-worker冻结对象 - Freeze objects using web-worker 将对象传递给 web 工作人员 - Passing objects to a web worker 来自web worker的setTimeout - setTimeout from a web worker 如何从Web工作者调用共享工作者? - How to call shared worker from the web worker? 使用React获取Web Worker - Fetch in a Web Worker using React
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM