Передать объект по ссылке от / к веб-работнику

Возможно ли передать объект из / в webWorker из / в основной поток по ссылке? Я прочитал здесь информацию о передаваемых объектах.

В Chrome 13 появилась отправка ArrayBuffers в / из Web Worker с использованием алгоритма, называемого структурированным клонированием. Это позволило API postMessage () принимать сообщения, которые были не просто строками, а сложными типами, такими как объекты File, Blob, ArrayBuffer и JSON. Структурное клонирование также поддерживается в более поздних версиях Firefox.

Я просто хочу передать информацию, а не объект с методами. Просто как-то так (но с большим количеством информации, несколько МБ, так что основной поток не должен получать копию объекта):

var test = {
    some: "data"
}

3 ответа

Как только у вас есть некоторые данные в объекте (это: {bla:666, color:"red"}Вы должны будете скопировать это, и нет никакого способа избежать этого. Причина в том, что у вас нет контроля над объектом, в котором хранится память, поэтому вы не можете передать его. Единственная память, которая может быть передана, это память, выделенная для переносимых объектов - типизированных массивов.

Поэтому, если вам нужно передать некоторые данные, вы должны заранее продумать и использовать переносимый интерфейс. Также имейте в виду, что даже когда объект копируется, скорость передачи очень высокая.

Я написал библиотеку, которая преобразует объект в двоичные данные (следовательно, переносимые), но это не быстрее, чем собственная передача, на самом деле это намного медленнее. Единственное преимущество заключается в том, что он позволяет передавать неподдерживаемые типы данных (например, Function).

На самом деле да, это возможно в (сюрприз, сюрприз!) Chrome 17+ и Firefox 18+ для определенных объектов ( см. Здесь).

// Create a 32MB "file" and fill it.
var uInt8Array = new Uint8Array(1024 * 1024 * 32); // 32MB
for (var i = 0; i < uInt8Array.length; ++i) {
  uInt8Array[i] = i;
}
worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);

Вы также можете применить это к строкам, преобразовав строку в буфер массива и из него, используя эту библиотеку, как показано ниже.

//inside the worker
function post_string(the_string){
    var my_array_buffer = string16.stringToArray(the_string).buffer;
    postMessage( my_array_buffer, [my_array_buffer] );
}

Затем, чтобы прочитать массив буферов как строку:

window.onmessage = function decode_buffer(evt){
    var buffer = evt.data;
    var str = string16.arrayToString(buffer);
    console.log("From worker: " + str);
    return str;
}


Источники: разработчик Google и разработчик Mozilla

Это невозможно. Вы должны отправить объект, обновить его на рабочем месте, а затем вернуть обновленную версию в основной поток.

Если вы хотите передать объект только с информацией, вам нужно только передать свой объект в виде строки

myWorker.postMessage(JSON.stringify(myObject)); 

разобрать объект внутри вашего работника

JSON.parse(myObject)

и, наконец, вернуть ваш обновленный объект в основной поток. Взгляните также на ParallelJs - библиотеку, облегчающую работу с веб-работниками

Другие вопросы по тегам