【问题标题】:How to pass custom class instances through Web-Workers?如何通过 Web-Workers 传递自定义类实例?
【发布时间】:2015-11-04 08:36:57
【问题描述】:

由于 Web-Worker JSON 在线程之间序列化数据,这样的事情不起作用:

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

结果将是一个失去foobar原型方法的简单对象。

是否可以在不丢失原型方法的情况下将自定义对象传回主线程?比如,ArrayBuffer 可以做到这一点吗?我对那些东西不熟悉,所以我有点迷茫。

【问题讨论】:

    标签: javascript buffer web-worker data-transfer arraybuffer


    【解决方案1】:
    1. 假设您对客户端和 Web 服务都进行了编程,您可以在双方都定义 Animal 函数
    2. 然后你可以添加到 Animal.prototype(两边)toJson 方法来传递你需要重新创建对象的信息(并且可以选择一些属性来定义类名)
    3. 您定义一个使用反向过程的 reviver
    4. 那么当你发帖时你必须总是 JSON.stringify(e)
    5. 在 onmessage 中你 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);
      }
      

    【讨论】:

    • 感谢您的评论埃米利奥。虽然您的脚本不是 100% 有效,但我明白了。但是一个简单的new Animal(JSON.parse(e.data)) 不会做同样的事情吗?不需要复活器?还是您的解决方案更快一些?我的主要目标是将大部分工作保留在工作线程中,而不会阻塞主线程。
    • 是的,不是 100% 的功能(我写的是“在飞行中”)。
    • 如果你知道你总是转移一个你不需要所有这些东西的动物,你可以简单地传递最小的数据来重新创建它。但是,如果您可以传递任何类型的任何内容,则可以使用此方法。即:var zoo = new Zoo({jail1: new Lion('pepe',12), jail2: new Tigger('winny', 5)}); worker.postMessage(zoo);
    猜你喜欢
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    相关资源
    最近更新 更多