javascript 中的 WebWorkers API 允许您使用浏览器中的 worker.postMessage 和 Worker 中的 postMessage 在工作线程和主线程之间传递对象。

我一直在玩,不仅 postMessage 传递数组和对象,甚至还有 RegExp 实例,所以我假设这些对象实现了一些接口(interface)。例如对于字符串转换,您实现 .toString 方法:

"" + {toString: function() {return "Hello world!"}}; //prints `Hello world!`

同样,您可以实现 toJSON 方法:
JSON.stringify({toJSON: alert});
//Throws `TypeError: 'alert' called on an object that does not implement interface Window.`
//  - demonstrating that toJSON is being called

我的问题是,我应该为 postMessage 实现什么才能让我的 Player 类通过通信 channel :
function Player(name) {
  this.name = name;
}
Player.prototype = Object.create(EventEmitter2.prototype);

我特意在这里添加了继承部分 - 我需要让对象保持 实例 的东西,而不仅仅是数据持有者。就像 RegExp 一样,我需要通过我定义的一个或多个方法来重建它 - 如果所需的上下文(类型定义,例如 EventEmitter2 )没有在新范围中定义,则必须失败。

最佳答案

唉,你不能。您不能指定自己的序列化器/反序列化器(或编码器/解码器)。你可以保留对象结构,这在大多数情况下已经足够了,但是像构造函数和函数这样的信息不会通过。

我是这样知道的:

负责 web worker 的 postMessage 的规范部分(顺便说一下,它与窗口的 postMessage 相同)可以在这里找到:https://html.spec.whatwg.org/multipage/comms.html#dom-messageport-postmessage

这是很多无趣的技术内容,但重要的部分是:



结构化克隆算法在这里:https://html.spec.whatwg.org/multipage/infrastructure.html#structured-clone

如您所见,事情看起来非常严峻。它检查内置对象和值(如 Number 或 Blob),并相应地构造它们。您可以传递任意对象,但只会保留它们的结构。

所以,你可以做什么?

  • 接受。只有数据才能通过,就像 JSON 一样,只是更受限制。这实际上并没有那么糟糕,并且鼓励分离传输层和实现。
  • 实现您自己的编码器/解码器,包装 postMessage 等。这实际上并没有那么难,而且可以是一个很好的练习。
  • 痛哭流涕。我喜欢这个选项,它有助于处理日常生活。
  • 关于javascript - 我需要实现什么接口(interface)才能允许对象通过 WebWorker 的 postMessage 传递?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32854626/

    10-12 12:25