2013-04-17 16 views
22

Obecnie mam ten kod w celu utworzenia pracownika WWW:Korzystanie zbywalne obiekty ze Pracownik internetowej

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

a nastepnie numer webwork.js dla pracownika Web:

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); 
} 

Teraz chcę przenieść 128 megabajta ArrayBuffer z tym kodem:

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

Teraz, gdy podobno przesłałem zmienną r, w jaki sposób mogę uzyskać do niej dostęp z samego pracownika sieci. Próbowałem event.r, tylko r, self.r i innych rzeczy, takich jak próbuje dodać drugi argument funkcji dla tablicy ArrayBuffers, ale nic nie działa.

Jak uzyskać dostęp do przesłanych zmiennych z Web Worker?

+0

nie będzie w ' event.data'? – bfavaretto

+0

Nie wydaje się tak. Jeśli używam "w.postMessage (0, [r]);", to "event.data" jest 0, ale nie wiem, gdzie znajduje się tablica ArrayBuffers, nawet poprzez sprawdzenie wszystkich właściwości wydarzenie. Nie mogę tego znaleźć. –

Odpowiedz

26
PostMesage(aMessage, transferList) 

w transferList należy podać uniwersalnych obiektów, które zawarte w aMessage:

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

Z drugiej strony:

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

Czy ktoś wie, czy to przenosi własności, czy robi kopię? Próbowałem i wygląda na to, że przenosi prawo własności. – user1311069

+0

Utwórz ArrayBuffer i Int8Array tylko raz! Następnie wysyłaj go tam iz powrotem. W przeciwnym razie używanie obiektów przenośnych nie ma sensu. – Pawel

+0

@Pawel możesz wyjaśnić, w jaki sposób możesz przesyłać go dalej? Po otrzymaniu tablicy, jeśli spróbujesz ponownie ją przeczytać, przeglądarka narzeka, że ​​"ArrayBuffer w indeksie 0 jest już wykastrowany." – RedShift

0

Spróbuj w.postMessage ([0, r]). Aby móc korzystać z obiektów przenośnych, należy przekazać bufor tablicy jako drugi element tablicy. Zobacz this

-2

działa to dla mnie:

// na Głównym

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

// W wątku pracownik w obsługi komunikatów,

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

To tylko * klon * ArrayBuffer; nie przenosić prawa własności między wątkami. – hanenbro

32

odpowiedzi udzielonej przez SBR działa, ale spowodowałoby to wykonanie kopii danych przed wysłaniem do pracownika. To może być powolne w przypadku dużej ilości danych.
Aby użyć "obiektów zbywalnych", faktycznie przenosi się prawo własności obiektu do lub z pracownika WWW. To jak przekazywanie przez odniesienie, gdy kopia nie jest tworzona. Różnica między nim a normalnym przejazdem polega na tym, że strona, która przesłała dane, nie ma już do niego dostępu.

Wierzę, że droga należy wysłać dane w przykładzie jest:

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

I sposób chcesz uzyskać do niego dostęp w pracownika internetowej:

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

W moim wniosku Musiałem wysłać dużą czcionkę Float64Array z webownika do głównego wątku, bez kary za wykonanie kopii. Trzeba było wielu prób, błędów i poszukiwań, więc pomyślałem, że powinienem dołączyć ten przykład tutaj dla każdego, kto utknął z podobnym problemem.
Jest to kod, który pracował po stronie pracownika (arr jest mój Float64Array):

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

na odbiorze głównego wątku mam:

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

Zauważ, że to działa w Chrome, ale może nie większość innych przeglądarek od tej daty (jeszcze nie próbowałem.)

Ponadto, jeśli chcesz wysłać inne informacje oprócz dużej tablicy, można to zrobić:

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

na odbiorze (w tym przykładzie Menem) wątek:

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

Ta odpowiedź jest lepsza niż zaakceptowana odpowiedź, ponieważ znacznie lepiej wyjaśnia cel drugiego parametru tablicy. – moron4hire

0

jeśli chcesz łatwo użyć pracownika internetowej, można spróbować ten mały lib: WW

nadzieję, że pomoże

Powiązane problemy