Подтвердить что ты не робот

Использование переносимых объектов из веб-рабочего

В настоящее время у меня есть этот код для создания веб-рабочего:

w = new Worker("webwork.js");
w.onmessage = function(event) { alert(event.data); }

И затем код 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);
}

Теперь я хочу передать 128-мегабайт ArrayBuffer с помощью этого кода:

var r = new ArrayBuffer(1048576*128);
w.postMessage(0, [r]);

Теперь, когда я предположительно передал переменную r, как мне получить доступ к ней из самого веб-рабочего. Я пробовал event.r, просто r, self.r и другие вещи, такие как попытка добавить второй аргумент функции для массива ArrayBuffers, но ничего не работает.

Как я могу получить доступ к переданной переменной (-ами) от веб-рабочего?

4b9b3361

Ответ 1

PostMesage(aMessage, transferList)

В transferList вы должны указать переносимые объекты, которые содержатся в aMessage:

var objData =
{
    str: "string",
    ab: new ArrayBuffer(100),
    i8: new Int8Array(200)
};
objWorker.postMessage(objData, [objData.ab, objData.i8.buffer]);

С другой стороны:

self.onmessage = function(objEvent)
{
    var strText = objEvent.data.str;
    var objTypedArray = objEvent.data.ab;
    var objTypedArrayView = objEvent.data.i8;
}

Ответ 2

Ответ, заданный sbr, работает, но это приведет к копированию данных, которые будут сделаны до отправки работнику. Это может быть медленным для большого количества данных.
Чтобы использовать "переносимые объекты", вы фактически передаете право собственности на объект на веб-пользователя или у него. Это как передача по ссылке, где копия не сделана. Разница между ним и обычной передачей по ссылке заключается в том, что сторона, которая передала данные, больше не может получить к ней доступ. Я верю, что вам следует отправить данные в вашем примере:

w.postMessage(r,[r]);  // first arg is r, not 0 as in the question

И как вы можете получить доступ к нему в веб-работнике:

addEventListener('message', function(event) {
    var r = event.data;
});

В моем собственном приложении мне нужно было отправить большой напечатанный Float64Array от веб-рабочего в основной поток без ущерба для производительности копии. Мне потребовалось много проб и ошибок и поиска, поэтому я решил, что должен включить этот пример для всех, кто застрял в аналогичной проблеме.
Это код, который работал на стороне рабочего (arr - мой Float64Array):

self.postMessage(arr.buffer, [arr.buffer]);

В принимающем основном потоке я:

theWorker.addEventListener('message', function(ev) {
    var arr = new Float64Array(ev.data);  // just cast it to the desired type - no copy made
    // ...
});

Обратите внимание, что это работает в Chrome, но, возможно, не в большинстве других браузеров с этой даты (еще не пробовал).

Кроме того, если вы хотите отправить другую информацию в дополнение к большому массиву, вы можете сделать это:

self.postMessage({foo:"foo", bar:arr.buffer}, [arr.buffer]);

В принимающем (в этом примере основном) потоке:

theWorker.addEventListener('message', function(event) {
    var foo = event.data.foo;
    var arr = new Float64Array(event.data.bar);  // cast it to the desired type
    // ...
});

Ответ 3

Попробуйте w.postMessage([0, r]). Чтобы использовать переносимые объекты, нужно передать буфер массива в качестве второго элемента массива. См. this

Ответ 4

если вы хотите легко пользоваться веб-рабочим, вы можете попробовать эту небольшую библиотеку: WW

надеюсь, что это поможет

Ответ 5

это работает для меня:

//в главном

var x = new ArrayBuffer(1048576*128);
w.postMessage({buffer: x});

//В рабочем потоке, в обработчике сообщений,

processMessage: function(ev){
    var buffer = ev.data.buffer,
    // other stuff . buffer is referenced correctly here. 
}