【问题标题】:prototype not working within web worker原型在网络工作者中不起作用
【发布时间】:2014-02-20 07:38:11
【问题描述】:

简单地说,我正在尝试在 web worker 中创建一个函数原型,而 chromium 抛出了这个错误:

Uncaught TypeError: Object #<DedicatedWorkerContext> has no method 'compute'

我认为需要一些示例代码。这是我工作日的结束,所以我很快就把它放在一起。整个下午都让我难以置信。我希望这是我明天早上回来说“啊哈”的问题之一,但如果我不会,我想我也会在这里问。

page.js

function threaded() { 
   var thread = new Worker('worker.js');
   thread.postMessage({a: 1 b: 2});
   thread.onMessage = function (e) { 
     console.log(e.data)
   });
}
threaded();

worker.js

var foo = function(a,b) { 
   this.a = a
   this.b = b
   this.result = false;
   this.compute();
};

foo.prototype.compute = function() { 
   this.result = this.a * this.b;
};

onmessage = function(e) { 
   var msg = foo(e.data.a,e.data.b)
   postMessage(msg)
};

我也尝试过以不同的方式传唤 worker.js 以将 foo() 包含在 onmessage 中,如下所示,但收到以下错误:

Uncaught TypeError: Cannot set property 'a' of undefined

worker-take2.js

onmessage = function(e) { 

   var foo = function(a,b) { 
      this.a = a
      this.b = b
      this.result = false;
      this.compute();
    };

   foo.prototype.compute = function() { 
     this.result = this.a * this.b;
   };

   var msg = foo(e.data.a,e.data.b)
   postMessage(msg)
};

【问题讨论】:

  • 顺便说一句,它也不会在网络工作者中工作。因此,在询问“prototype not working in web worker”之前,值得先在“正常”环境中检查它

标签: javascript html web-worker


【解决方案1】:

问题是您正在执行foo,而不是声明它的new 实例。因此,thisfoo 的上下文中计算为专用的工作上下文,而不是对象实例上下文。

试试这个:

var foo = function(a,b) { 
   this.a = a
   this.b = b
};

foo.prototype.compute = function() { 
   return this.a * this.b;
};

onmessage = function(e) { 
   var msg = new foo(e.data.a,e.data.b).compute();
   postMessage(msg)
};

有一些重要的变化需要注意。首先,我更改了compute 以返回结果,而不是将其设置为属性。请记住,当使用 prototype 时,您明确地创建了在对象实例之间共享的方法,因此暗示您以面向对象的方式使用该代码。

其次,我更改了foo 的构造函数,使其不会立即调用compute。相反,compute 在声明对象实例后被调用。

试试看!

【讨论】:

  • “啊哈!”,叹息。我知道答案会打我的脸。我想我会把这归咎于新英格兰的所有积雪和刚刚克服食物中毒......是的,就是这样。不过,真的,我发现自己最近远离了 JavaScript 中的 new。不是var x = new Array();,而是var x = [];。第二点我没把握。对我来说,compute() 实际上是init(),它调用了更多方法。为什么要把它移出原来的函数声明?
  • 好吧,我假设您想在这里保留面向对象的模式,并且在原始示例中,您在计算中设置结果,如果您想保留您可以这样做:var f = new foo(e.data.a, e.data.b); var msg = f.result 老实说,您这里不需要对象,只需:function compute(a, b) { return a * b }var msg = compute(e.data.a, e.data.b);
  • 嗯,好的。实际上,该对象是一个验证的清单。这在计算方面相当繁重。所以我正在使用一个网络工作者和一系列功能。该对象正在帮助我组织所有功能。换句话说,该示例代码快速而肮脏地说明了我在最短的代码量中遇到的问题。再次感谢您的回答。当我看到它时,我知道它会那么简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-14
  • 2020-05-17
相关资源
最近更新 更多