广州web培训
达内广州五羊中心

18589266248

热门课程

JS中的并行处理:Workers 嵌套

  • 时间:2016-12-26 14:20
  • 发布:广州web培训
  • 来源:拿客

理论上,你可以嵌套使用worker,就像在主线程中定义一个worker一样。

数据传递

达内广州前端开发培训认为你在worker数据传递的过程中有些需要注意的边缘情况。你可以传递数值,字符串,数组,也可以传递序列化/反序列化的对象。然而,你却不应该依赖序列化来保持数据结构,实际上,postMessage用到了一种数据克隆算法,它会生成一些额外的属性比如RegExps和Blobs以及一些循环引用。

这就是说,你需要将你要传递的数据最小化。你不可以传递functions ,即使是支持的类型也会有一些限制,这些也很容易产生一些难以发现的bug。如果你将你的API定义为只传递字符串,数值,数组和对象的话,那你可能会避过这些问题。

循环引用

如果你有一个很复杂的对象,那么里面很可能存在循环引用,这时如果你将它序列化成JSON,你将会得到一个TypeError: Converting circular structure to JSON.

let a = {};

let b = {a};

a.b = b;

JSON.stringify({a,b}); // Error

然而你可以在postMessage中放心的使用,从而你就可以在worker中使用。

Transferable objects

为了防止同时修改同一变量的场景,你传递给postMessage的所有变量都会复制一份,这样确保了你多个线程不会修改同一个变量。但如果你想要传一个非常大的数据的话,你就会发现复制操作是很慢的。比如,如果你在做一些图片相关的运算,你可能会传递整个图片信息,就可能会遇到复制性能的瓶颈。

好在有transferable object,用transfer来代替copy,比如ArrayBuffer是transferable对象,而我们可以把任何类型的对象放在ArrayBuffer中。

如果你transfer一个对象,之前拥有它的线程被锁定权限,它确保了数据没有复制之前,不会被同时修改。

这时postMessage的代码段就有点尴尬了:

const ab = new ArrayBuffer(100);

console.log(ab.byteLength); // 100

worker.postMessage(ab, [ab]);

console.log(ab.byteLength); // 0

确保在postMessage中传递第二个参数,否则数据将会被复制。

const ab = new ArrayBuffer(100);

console.log(ab.byteLength); // 100

worker.postMessage(ab);

console.log(ab.byteLength); // 100

广州Web前端培训就到广州达内,详情请登陆广州达内Web前端培训官网(gz.web.tedu.cn)!

上一篇:如何理解JavaScript 数组slice与splice?
下一篇:JS中的并行处理:行内Workers

马上预约三天免费体验课

姓名:

电话:

JS中的并行处理:Workers 嵌套

如何理解JavaScript 数组slice与splice?

选择城市和中心
江西省

贵州省

广西省

海南省