这是一个非常合适的方法,用于切换 主页-worker - 或是相反的 - 之间的消息。
通过转让所有权(可转让对象)来传递数据
Google Chrome 17 与 Firefox 18 包含另一种性能更高的方法来将特定类型的对象(可转让对象) 传递给一个 worker/从 worker 传回 。可转让对象从一个上下文转移到另一个上下文而不会经过任何拷贝操作。这意味着当传递大数据时会获得极大的性能提升。如果你从 C/C++ 世界来,那么把它想象成按照引用传递。然而与按照引用传递不同的是,一旦对象转让,那么它在原来上下文的那个版本将不复存在。该对象的所有权被转让到新的上下文内。例如,当你将一个ArrayBuffer对象从主应用转让到Worker 中,原始的ArrayBuffer被清除并且无法使用。它包含的内容会(完整无差的)传递给 Worker 上下文。
| // Create a 32MB "file" and fill it. var uInt8Array = new Uint8Array(1024*1024*32); // 32MB for (var i = 0; i < uInt8Array .length; ++i) { uInt8Array[i] = i; } worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]); |
生成subworker
如果需要的话 Worker 能够生成更多的 Worker。这样的被称为 subworker,它们必须托管在与父页面相同的源内。同理,subworker 解析 URI 时会相对于父 worker 的地址而不是自身的页面。这使得 worker 容易监控它们的依赖关系。 Chrome 目前并不支持subworker。
嵌入式 worker
目前没有一种「官方」的方法能够像<script>元素一样将 worker 的代码嵌入的网页中。但是如果一个<script>元素没有src 特性,并且它的type特性没有指定成一个可运行的 mime-type,那么它就会被认为是一个数据块元素,并且能够被 JavaScript 使用。「数据块」是 HTML5 中一个十分常见的特性,它可以携带几乎任何文本类型的数据。所以,你能够以如下方式嵌入一个 worker:
| <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>MDN Example - Embedded worker</title> <script type="text/js-worker"> // 该脚本不会被 JS 引擎解析,因为它的 mime-type 是 text/js-worker。 var myVar = "Hello World!"; // 剩下的 worker 代码写到这里。 </script> <script type="text/javascript"> // 该脚本会被 JS 引擎解析,因为它的 mime-type 是 text/javascript。 function pageLog (sMsg) { // 使用 fragment:这样浏览器只会进行一次渲染/重排。 var oFragm = document.createDocumentFragment(); oFragm.appendChild(document.createTextNode(sMsg)); oFragm.appendChild(document.createElement("br")); document.querySelector("#logDisplay").appendChild(oFragm); } </script> <script type="text/js-worker"> // 该脚本不会被 JS 引擎解析,因为它的 mime-type 是 text/js-worker。 onmessage = function (oEvent) { postMessage(myVar); }; // 剩下的 worker 代码写到这里。 </script> <script type="text/javascript"> // 该脚本会被 JS 引擎解析,因为它的 mime-type 是 text/javascript。 // 在过去...: // 我们使用 blob builder // ...但是现在我们使用 Blob...: var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type="text/js-worker"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"}); // 创建一个新的 document.worker 属性,包含所有 "text/js-worker" 脚本。 document.worker = new Worker(window.URL.createObjectURL(blob)); document.worker.onmessage = function (oEvent) { pageLog("Received: " + oEvent.data); }; // 启动 worker. window.onload = function() { document.worker.postMessage(""); }; </script> </head> <body><div id="logDisplay"></div></body> </html> |









