首頁  >  文章  >  web前端  >  HTML5新特性之Web Worker

HTML5新特性之Web Worker

黄舟
黄舟原創
2017-03-30 11:54:061307瀏覽

1、概述

JavaScript語言採用的是單一線程模型,也就是說,所有任務排成一個佇列,一次只能做一件事。無法充分發揮JavaScript的潛能。就是為JavaScript創造多執行緒環境,讓主執行緒將一些任務指派給子執行緒 在主執行緒運行的同時,子執行緒在後台運行,兩者互不干擾。主執行緒。 ##同域限制:子執行緒載入的腳本文件,必須與主執行緒的腳本文件在同一個網域。即document、window、parent這些對象,子執行緒都無法得到。變數和函數,也不能執行alert和confirm方法,不過可以執行setInterval和setTimeout,以及使用XMLHttpRequest物件發出AJAX請求。即子執行緒無法開啟本機的檔案系統(file://),它所載入的腳本,必須來自網路。支援的瀏覽器包括IE 10+、Firefox 3.6+、Safari 4.0+、Chrome 和Opera 11,但手機瀏覽器還不支援。在主執行緒內部,採用new指令呼叫Worker方法,可以新建一個子執行緒。上面程式碼中是work.js。 子執行緒新建之後,並沒有啟動,必要等待主執行緒呼叫postMessage方法,也就是發出訊號之後才會啟動。

if (window.Worker) {    // 支持} else {    // 不支持}

postMessage方法的參數,就是主執行緒傳給子執行緒的訊號。它即可以是一個

字串

,也可以是一個物件。

var worker = new Worker('work.js');
    3、子執行緒的
  • 事件

    監聽

  • 在子執行緒內,必須有一個
  • 回呼函數

    ,監聽message事件。

    worker.postMessage('hello world');
  • self代表子執行緒自身,self.addEventListener表示對子執行緒的message事件指定回呼函數(直接指定onmessage
  • 屬性

    的值也可以)。回呼

    函數的參數
  • 是一個事件對象,它的data屬性包含主執行緒發來的訊號。 self.postMessage則表示,子執行緒向主執行緒發送一個訊號。
  • 根據主執行緒發出的不同的訊號值,子執行緒可以呼叫不同的方法。

    worker.postMessage({method: 'each', args: ['work']});
  • 4、主執行緒的事件監聽

主執行緒也必須指定message事件的回呼函數,監聽子執行緒發出的訊號。

//File: work.jsself.addEventListener('message', function(e) {

    self.postMessage('You said: ' + e.data);

}, false);

5、

錯誤處理

主執行緒可以監聽子執行緒是否發生錯誤。如果發生錯誤,會觸發主執行緒的error事件。

'message',  method = args = reply =);

6、關閉子執行緒

使用完畢後,為了節省系統資源,我們必須在主執行緒呼叫terminate方法,手動關閉子執行緒。

// File: main.jsworker.addEventListener('message', function(e) {
    console.log(e.data);
}, false);

也可以子執行緒內部關閉自身。

worker.onerror(function(e) {
    console.log(e);
});// orworker.addEventListener('error', function(e) {
    console.log(e);
}, false);
7、主執行緒與子執行緒的資料通訊

主執行緒與子執行緒之間的通訊內容,可以是文本,也可以是物件。需要注意的是,這種通訊是拷貝關係,也就是傳值而不是傳址,子執行緒對通訊內容的修改,不會影響到主執行緒。事實上,瀏覽器內部的運作機制是,先將通訊內容串行化,然後把串列化後的字串寄給子線程,後者再將它還原。

主執行緒也子執行緒這間也可以交換二進位數據,例如File、Blob、ArrayBuffer等對象,也可以在執行緒之間傳送。

但是,用拷贝方式发送二进制数据,会造成性能问题。比如,主线程向子线程发送一个500MB文件,默认情况下浏览器会生成一个原文件的拷贝。为了解决这个问题,JavaScript允许主线程把二进制数据直接转移给子线程,但是一旦转移,主线程就无法再使用这些二进制数据了,这是为了防止出现多个线程同时修改数据的麻烦局面。这种转移数据的方法,叫做Transferable Objects。

如果要使用该方法,postMessage方法的最后一个参数必须是一个数组,用来指定前面发送的哪些值可以被转移给子线程。

worker.postMessage(arrayBuffer, [arrayBuffer]);

8、同页面的Web Worker

通常情况下,子线程载入的是一个单独的JavaScript文件,但是也可以载入与主线程在同一个网页的代码。假设网页代码如下:

<!DOCTYPE html>
    <body>
        <script id="worker" type="app/worker">

            addEventListener(&#39;message&#39;, function() {
                postMessage(&#39;Im reading Tech.pro&#39;);
            }, false);        </script>
    </body></html>

我们可以读取页面的script,用worker来处理。

var blob = new Blob([document.querySelector(&#39;#workere&#39;).textContent]);

这里需要把代码当作二进制数据读取,所以使用Blob接口。然后,这个二进制对象转为URL,再通过这个URL创建worker。

var url = window.URL.createObjectURL(blob);var worker = new Worker(url);

部署事件监听代码。

worker.addEventListener(&#39;message&#39;, function(e) {
    console.log(e.data);
}, false);

最后启动worker。

worker.postMessage(&#39;&#39;);

整个页面的代码如下:


    
        

        <script>
            (function() {                
            var blob = new Blob([document.querySelector(&#39;#worker&#39;).textContent]);                
            var url = window.URL.createObjectURL(blob);                
            var worker = new Worker(url);

                worker.addEventListener(&#39;message&#39;, function(e) {
                    console.log(e.data);
                }, false);

                worker.postMessage(&amp;#39;&amp;#39;);
            })();        </script>
    

可以看到,主线程和子线程的代码都在同一个网页上面。

上面所讲的Web Worker都是专属于某个网页的,当该网页关闭,worker就自动结束。除此之外,还有一种共享式的Web Worker,允许多个浏览器窗口共享同一个worker,只有当所有窗口关闭,它才会结束。这种共享式的Worker用SharedWorker对象来创建,因为适用场合不多,这里就省略了。

以上是HTML5新特性之Web Worker的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn