2015-08-11 17 views
5

Ponieważ Web Worker JSON serializacji danych pomiędzy wątkami, coś takiego nie działa:Jak przekazywać instancje klasy niestandardowej za pośrednictwem pracowników sieci Web?

worker.js

function Animal() {} 
Animal.prototype.foobar = function() {} 

self.onmessage = function(e) { 
    self.postMessage({animal: new Animal()}) 
} 

main.js

let worker = new Worker('worker.js') 

worker.onmessage = function(e) { 
    console.log(e.data) 
} 

worker.postMessage('go!') 

Wynik byłby prosty obiekt ze stratą prototypowej metody foobar.

Czy możliwe jest przeniesienie niestandardowego obiektu z powrotem do głównego wątku bez utraty jego prototypowych metod? Czy byłoby to możliwe z ArrayBuffer? Nie znam tych rzeczy, więc jestem trochę zagubiony.

Odpowiedz

1
  1. Zakładając zaprogramować zarówno klienta jak i usługa można zdefiniować funkcję zwierzęcia w boths stronach
  2. Następnie można dodać do Animal.prototype (w obie strony) toJson sposób przekazać potrzebne informacje do odtworzenia przedmiot (a może wybrać jakiś atrybut definiujący className)
  3. zdefiniować Reviver które wykorzystują proces odwrotny
  4. wtedy kiedy piszesz musisz zawsze JSON.stringify (e)
  5. W onmessage ty JSON.parse (m, reviver)

    function Animal(name, age){ 
        var private_name = name; 
        this.public_age = age; 
        this.log = function(){ 
        console.log('Animal', private_name, this.public_age); 
        } 
        this.toJson = function(){ 
        return JSON.stringify({ 
         __type__:'Animal', // name of class 
         __args__:[this.public_age, private_name] // same args that construct 
        }); 
        }   
    } 
    
    Animal.prototype.age = function(){ 
        return this.public_age; 
    } 
    
    var a = new Animal('boby', 6); 
    
    worker.postMessage(JSON.stringify(a)); 
    
    function reviver(o){ 
        if(o.__type__){ 
        var constructor=reviver.register[o.__type__]; 
        if(!constructor) throw Error('__type__ not recognized'); 
        var newObject = {}; 
        return constructor.apply(newObject, o.__args__); 
        } 
        return o; 
    } 
    
    reviver.register={}; // you can register any classes 
    
    reviver.register['Animal'] = Animal; 
    
    worker.onmessage = function(m){ 
        var a = JSON.parse(e, reviver); 
    } 
    
+0

Dzięki za komentarz Emilio. Chociaż twój skrypt nie jest w 100% funkcjonalny, rozumiem. Ale czy proste "nowe zwierzę (JSON.parse (e.data)) nie zrobi tego samego? Nie potrzebujesz odrodzonego? A może twoje rozwiązanie jest nieco szybsze? Moim głównym celem jest utrzymanie większości prac w ramach pracownika, bez blokowania głównego wątku. –

+0

Tak, nie jest w 100% funkcjonalny (napisałem "w locie"). –

+0

Jeśli wiesz, że zawsze przenosisz zwierzę, nie potrzebujesz tego wszystkiego, możesz po prostu przekazać minimalną ilość danych, aby je odtworzyć. Ale jeśli możesz przekazać cokolwiek dowolnego typu, możesz użyć tego podejścia. Np .: 'var zoo = new Zoo ({jail1: new Lion ('pepe', 12), jail2: new Tigger ('winny', 5)}); worker.postMessage (zoo); ' –

Powiązane problemy