我需要实现什么接口才能允许通过 WebWorker 的 postMessage 传递对象?
What interface do I need to implement to allow object to be passed through WebWorker's postMessage?
WebWorkers API in javascript 允许您在工作线程和主线程之间传递对象,在浏览器中使用 worker.postMessage
,在 Worker 中使用 postMessage
。
我一直在玩,不仅 postMessage
传递了数组和对象,甚至还传递了 RegExp 实例,所以我假设这些对象实现了一些接口。例如对于字符串转换,您实现 .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
class 通过通信渠道:
function Player(name) {
this.name = name;
}
Player.prototype = Object.create(EventEmitter2.prototype);
我特意在此处添加了继承部分 - 我需要对象保留某些东西的实例,而不仅仅是数据持有者。就像 RegExp
一样,我需要通过我定义的一个或多个方法对它进行 重构 - 如果需要上下文(类型定义,例如 EventEmitter2
) 未在新范围内定义。
唉,你不能。您不能指定自己的 serialiser/deserialiser(或 marshaller/unmarshaller)。虽然你可以保留对象结构,在大多数情况下这已经足够了,但是构造函数和函数等信息不会通过。
我是这样知道的:
规范中负责网络工作者 postMessage
的部分(顺便说一句,与 window 的 postMessage
相同)可以在这里找到: https://html.spec.whatwg.org/multipage/comms.html#dom-messageport-postmessage
其中有很多无趣的技术内容,但重要的部分是:
Let message clone be the result of obtaining a structured clone of the message argument, [...]
结构化克隆算法在这里:https://html.spec.whatwg.org/multipage/infrastructure.html#structured-clone
如您所见,情况看起来很严峻。它检查内置对象和值(如 Number 或 Blob),并相应地构造它们。您可以传递任意对象,但只会保留它们的结构。
那么,你能做什么?
- 接受吧。只有数据通过,比如 JSON 只是更有限。这实际上并没有那么糟糕,并且鼓励分离传输层和实现。
- 实现您自己的 marshaller/unmarshaller,包装
postMessage
等。这实际上并没有那么难,而且可以是一个很好的练习。
- 痛哭流涕。我喜欢这个选项,它有助于处理日常生活。
WebWorkers API in javascript 允许您在工作线程和主线程之间传递对象,在浏览器中使用 worker.postMessage
,在 Worker 中使用 postMessage
。
我一直在玩,不仅 postMessage
传递了数组和对象,甚至还传递了 RegExp 实例,所以我假设这些对象实现了一些接口。例如对于字符串转换,您实现 .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
class 通过通信渠道:
function Player(name) {
this.name = name;
}
Player.prototype = Object.create(EventEmitter2.prototype);
我特意在此处添加了继承部分 - 我需要对象保留某些东西的实例,而不仅仅是数据持有者。就像 RegExp
一样,我需要通过我定义的一个或多个方法对它进行 重构 - 如果需要上下文(类型定义,例如 EventEmitter2
) 未在新范围内定义。
唉,你不能。您不能指定自己的 serialiser/deserialiser(或 marshaller/unmarshaller)。虽然你可以保留对象结构,在大多数情况下这已经足够了,但是构造函数和函数等信息不会通过。
我是这样知道的:
规范中负责网络工作者 postMessage
的部分(顺便说一句,与 window 的 postMessage
相同)可以在这里找到: https://html.spec.whatwg.org/multipage/comms.html#dom-messageport-postmessage
其中有很多无趣的技术内容,但重要的部分是:
Let message clone be the result of obtaining a structured clone of the message argument, [...]
结构化克隆算法在这里:https://html.spec.whatwg.org/multipage/infrastructure.html#structured-clone
如您所见,情况看起来很严峻。它检查内置对象和值(如 Number 或 Blob),并相应地构造它们。您可以传递任意对象,但只会保留它们的结构。
那么,你能做什么?
- 接受吧。只有数据通过,比如 JSON 只是更有限。这实际上并没有那么糟糕,并且鼓励分离传输层和实现。
- 实现您自己的 marshaller/unmarshaller,包装
postMessage
等。这实际上并没有那么难,而且可以是一个很好的练习。 - 痛哭流涕。我喜欢这个选项,它有助于处理日常生活。