我将一个空数组传递给一个worker,它应该填充数组并返回它 - 我知道还有其他方法可以做到这一点,但我更感兴趣的是为什么它不起作用,而不是让它工作
主要代码:
var arr = new Array(4)
console.log(arr.length)//outputs 4
var worker = new Worker("whatever.js")
worker.postMessage(arr)
工人代码
self.onmessage = function(msg){
console.log(msg.data.length)//outputs 0
}
如果我传入一个填充的数组,它就可以了。如果我甚至将数组的单个条目设置为一个值,它就可以工作。
为什么postMessage
函数崩溃非零长度,但是空数组,有没有办法避免这种情况? (除了手动分配值)
我使用的是Windows 7和Chrome 51
答案 0 :(得分:0)
数据通过structured cloning algorithm复制到工作人员,因此您的工作人员没有获得您创建的确切数组,这将是一个线程不安全的操作,因为数组是引用类型。这是MDN文档不完整的情况,一般情况下,结构化克隆算法等同于JSON.parse(JSON.stringify(x))
,但这是一个例外,因为JSON.parse(JSON.stringify(new Array(4)))
至少在chrome中产生[null, null, null, null]
和ff。
这里奇怪的行为可能部分是因为没有任何意义来创建具有这样的空槽的数组,甚至没有任何指示,例如new Array(4).forEach(i => console.log('foo'));
没有做任何事情。因此,结构化克隆算法会生成一个空数组。
请注意,结构化克隆算法不是JavaScript规范的一部分,它是HTML 5 spec的一部分,据我所知,它没有提供很多细节,所以我不完全确定它是如何工作的,但似乎专注于像fileData和Blobs这样的东西。请注意,克隆arraybuffer 是 Ecmascript spec的一部分。所有这些都是有道理的,工作人员对通信开销(这就是提出共享存储器结构的原因)的性能损失很大,这在很大程度上归功于相同的算法。因此,您想要在其中执行的计算必须足够强大,以超过启动和通信惩罚。因此,沟通渠道更关注那些低级别(在blob情况下基本上是二进制)数据结构是有道理的。