dgi*_*ian 52 javascript web-worker
我正在尝试通过postMessage函数将对象传递给Web worker.
这个对象是一个正方形,有一些功能可以在画布上绘制自己和其他一些东西.Web worker必须返回此对象的数组.
问题是当我用这个对象调用postMessage函数时,我收到一个错误:
Uncaught Error: DATA_CLONE_ERR: DOM Exception 25
我得到这个将对象发送给工人,反之亦然.
我认为错误是因为javascript必须序列化对象,但不能这样做因为对象具有内置函数.
有没有人遇到过类似的问题?你知道这方面的一些工作吗?
提前致谢.
eri*_*old 51
将对象发送给Web worker时,对象将被序列化,如果对象是可序列化对象,则稍后在Web worker中反序列化.
这意味着您发送给Web worker的对象的方法不能传递给Web worker(导致您遇到的错误),并且您需要为对象提供必要的方法/函数在Web工作者的环境中,并确保它们不是传递给Web worker的对象的一部分.
ben*_*ich 13
因为您怀疑具有功能的对象无法发布.具有递归引用的对象也是如此,但最近在某些浏览器中已经发生了变化.您可以在脚本开头执行测试,以确定用于发送/接收数据的功能,而不是冒着为每个帖子进行手动和昂贵的冗余序列化的风险.
我遇到了同样的问题并通过将几乎所有代码移动到worker中并且只在主线程中保留渲染器(包装2d上下文渲染器)来解决它.在worker中,我将用于画布的不同绘制调用序列化为(类型)数组中的数字.然后将此数组发布到主线程.
因此,例如,当我想绘制图像时,我drawImage()在worker中的worker worker渲染器实例上调用该方法.该调用被转换为类似于[13,1,50,40]绘制方法枚举,图像唯一ID及其xy坐标的内容.多个调用被缓冲并放在同一个数组中.在更新循环结束时,数组将发布到主线程.接收主渲染器实例解析数组并执行适当的绘制调用.
我最近在使用Web worker时遇到了同样的问题.我传给工人的任何东西都保留了它的所有属性,但神秘地丢失了它的所有方法.
您必须在Web worker脚本本身中定义方法.一种解决方法是importScripts类定义并手动设置__proto__您收到的任何属性.在我的情况下,我想传递一个grid对象,定义在grid.js(是的,我在2048年工作),并且这样做:
importScripts('grid.js')
onMessage = function(e) {
  e.data.grid.__proto__ = Grid.prototype;
  ...
}
当您将数据传递给 Web Worker 时,会使用结构化克隆算法制作数据副本。它在 HTML5 中指定(参见第 2.9 节:结构化数据的安全传递)。
MDN 有支持类型的概述。由于不支持函数,因此尝试克隆包含函数的对象将引发DATA_CLONE_ERR异常。
如果你有一个带有函数的对象怎么办?
如果函数不相关,请尝试创建一个仅包含要传输的数据的新对象。只要您仅使用受支持的类型,发送就可以工作。使用JSON.stringify和JSON.parse也可以用作解决方法,因为stringify忽略函数。
如果功能相关,则没有可移植的方式。有尝试使用的组合toString和eval(例如,用于由jsonfs库),但这并不适用于所有情况。例如,如果您的函数是本机代码,它就会中断。闭包也是有问题的。
对象和网络工作者的真正问题在于对象的方法。一个对象不应该只有方法而具有属性。
例如:
var myClass = function(){
    this.a = 5;
    this.myMethod = function(){}
}
var notParseableObject = new myClass();
var myClass2 = function(){
    this.a = 5;
}
var parseableObject = new myClass2();
第一个不会与postMessage一起工作(带有提到的错误消息),第二个将工作。
| 归档时间: | 
 | 
| 查看次数: | 40809 次 | 
| 最近记录: |