最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to pass custom class instances through Web-Workers? - Stack Overflow

programmeradmin0浏览0评论

Since Web-Worker JSON serialize data between threads, something like this doesn't work:

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!')

The oute would be a simple object with the loss of the foobar prototype method.

Is it possible to transfer the custom object back to the main thread without losing its prototype methods? Like, would this be possible with ArrayBuffer? I'm not familiar with that stuff, so I'm a bit lost.

Since Web-Worker JSON serialize data between threads, something like this doesn't work:

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!')

The oute would be a simple object with the loss of the foobar prototype method.

Is it possible to transfer the custom object back to the main thread without losing its prototype methods? Like, would this be possible with ArrayBuffer? I'm not familiar with that stuff, so I'm a bit lost.

Share Improve this question edited Aug 11, 2015 at 23:08 Martin Broder asked Aug 11, 2015 at 22:49 Martin BroderMartin Broder 2213 silver badges14 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2
  1. Assuming you program both the client and the webservice you can define the Animal function in boths sides
  2. Then you can add to Animal.prototype (in both sides) toJson method to pass the info you need to recreate the object (and may be choose some attribute to define the className)
  3. You define a reviver that use the reverse process
  4. Then when you post you must always JSON.stringify(e)
  5. In the onmessage you 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);
    }
    

There is a simple way without set prototypes, also without convert to string with JSON.stringify, you need to build to function:

  • toObject(instance):obj, instance is and instance class and will be converted to and object
  • toInstanceClass(obj):instance, obj is and object and will return and instance from your class

You need to pass your obj to the worker, in the worker you'll build your instance from your class, make all your operations and return like and obj

In your main thread you'll need to rebuild your instance from your class by the returned obj from worker, that's all.

发布评论

评论列表(0)

  1. 暂无评论