Передать объект по ссылке от / к веб-работнику
Возможно ли передать объект из / в 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 - библиотеку, облегчающую работу с веб-работниками