2015-11-05 4 views
3

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

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

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

var test = { 
    some: "data" 
} 
+0

Можете ли вы пояснить, почему метод в [переносимых объектов] (https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast) не делает то, что вы хотите? Разве что вы хотите, чтобы рабочий и основной поток имели доступ к одному и тому же объекту в памяти одновременно? –

ответ

0

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

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

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

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

JSON.parse(myObject) 

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

1

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

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

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

2

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

// 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]); 

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

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

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

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


Источники: Google Developer и Mozilla Developer

+0

Что такое ++ ++? Вы только написали это и надеетесь, что это будет правильно? – user1863152