亚洲最大看欧美片,亚洲图揄拍自拍另类图片,欧美精品v国产精品v呦,日本在线精品视频免费

  • 站長(zhǎng)資訊網(wǎng)
    最全最豐富的資訊網(wǎng)站

    HTML5新特性之Web Worker


    1、概述

    JavaScript語言采用的是單線程模型,也就是說,所有任務(wù)排成一個(gè)隊(duì)列,一次只能做一件事。隨著電腦計(jì)算能力的增強(qiáng),這一點(diǎn)帶來很大的不便,無法充分發(fā)揮JavaScript的潛能。龍其考慮到,F(xiàn)ile API允許JavaScript讀取本地文件,就更加如此了。

    Web Worker的目就,就是為JavaScript創(chuàng)造多線程環(huán)境,允許主線程將一些任務(wù)分配給子線程。在主線程運(yùn)行的同時(shí),子線程在后臺(tái)運(yùn)行,兩者互不干擾。等到子線程完成計(jì)算任務(wù),再把結(jié)果返回給主線程。因此,每一個(gè)子線程就好像一個(gè)“工人”(worker),默默地完成自己的工作。

    Web Worker有以下幾個(gè)特點(diǎn):

    • 同域限制:子線程加載的腳本文件,必須與主線程的腳本文件在同一個(gè)域。

    • DOM限制:子線程無法讀限網(wǎng)頁的DOM對(duì)象,即document、window、parent這些對(duì)象,子線程都無法得到。(但是,navigator對(duì)象和location對(duì)象可以獲得。)

    • 腳本限制:子線程無法讀取網(wǎng)頁的全局變量和函數(shù),也不能執(zhí)行alert和confirm方法,不過可以執(zhí)行setInterval和setTimeout,以及使用XMLHttpRequest對(duì)象發(fā)出AJAX請(qǐng)求。

    • 文件限制:子線程無法讀取本地文件,即子線程無法打開本機(jī)的文件系統(tǒng)(file://),它所加載的腳本,必須來自網(wǎng)絡(luò)。

    使用之前,檢查瀏覽器是否支持這個(gè)API。支持的瀏覽器包括 IE 10+、Firefox 3.6+、Safari 4.0+、Chrome 和 Opera 11,但是手機(jī)瀏覽器還不支持。

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

    2、新建和啟動(dòng)子線程

    在主線程內(nèi)部,采用new命令調(diào)用Worker方法,可以新建一個(gè)子線程。

    var worker = new Worker('work.js');

    Worker方法的參數(shù)是一個(gè)腳本文件,這個(gè)文件就是子線程所要完成的任務(wù),上面代碼中是work.js。由于子線程不能讀取本地文件系統(tǒng),所以這個(gè)腳本文件必須來自網(wǎng)絡(luò)端。如果下載沒有成功,比如出現(xiàn)404錯(cuò)誤,這個(gè)子線程就會(huì)默默地失敗。

    子線程新建之后,并沒有啟動(dòng),必需等待主線程調(diào)用postMessage方法,即發(fā)出信號(hào)之后才會(huì)啟動(dòng)。

    worker.postMessage('hello world');

    postMessage方法的參數(shù),就是主線程傳給子線程的信號(hào)。它即可以是一個(gè)字符串,也可以是一個(gè)對(duì)象。

    worker.postMessage({method: 'each', args: ['work']});

    3、子線程的事件監(jiān)聽

    在子線程內(nèi),必須有一個(gè)回調(diào)函數(shù),監(jiān)聽message事件。

    //File: work.jsself.addEventListener('message', function(e) {        self.postMessage('You said: ' + e.data);    }, false);

    self代表子線程自身,self.addEventListener表示對(duì)子線程的message事件指定回調(diào)函數(shù)(直接指定onmessage屬性的值也可以)?;卣{(diào)函數(shù)的參數(shù)是一個(gè)事件對(duì)象,它的data屬性包含主線程發(fā)來的信號(hào)。self.postMessage則表示,子線程向主線程發(fā)送一個(gè)信號(hào)。

    根據(jù)主線程發(fā)來的不同的信號(hào)值,子線程可以調(diào)用不同的方法。

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

    4、主線程的事件監(jiān)聽

    主線程也必須指定message事件的回調(diào)函數(shù),監(jiān)聽子線程發(fā)來的信號(hào)。

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

    5、錯(cuò)誤處理

    主線程可以監(jiān)聽子線程是否發(fā)生錯(cuò)誤。如果發(fā)生錯(cuò)誤,會(huì)觸發(fā)主線程的error事件。

    worker.onerror(function(e) {      console.log(e);  });// orworker.addEventListener('error', function(e) {      console.log(e);  }, false);

    6、關(guān)閉子線程

    使用完畢后,為了節(jié)省系統(tǒng)資源,我們必須在主線程調(diào)用terminate方法,手動(dòng)關(guān)閉子線程。

    worker.terminate();

    也可以子線程內(nèi)部關(guān)閉自身。

    self.close();

    7、主線程與子線程的數(shù)據(jù)通信

    主線程與子線程之間的通信內(nèi)容,可以是文本,也可以是對(duì)象。需要注意的是,這種通信是拷貝關(guān)系,即是傳值而不是傳址,子線程對(duì)通信內(nèi)容的修改,不會(huì)影響到主線程。事實(shí)上,瀏覽器內(nèi)部的運(yùn)行機(jī)制是,先將通信內(nèi)容串行化,然后把串行化后的字符串發(fā)給子線程,后者再將它還原。

    主線程也子線程這間也可以交換二進(jìn)制數(shù)據(jù),比如File、Blob、ArrayBuffer等對(duì)象,也可以在線程之間發(fā)送。

    但是,用拷貝方式發(fā)送二進(jìn)制數(shù)據(jù),會(huì)造成性能問題。比如,主線程向子線程發(fā)送一個(gè)500MB文件,默認(rèn)情況下瀏覽器會(huì)生成一個(gè)原文件的拷貝。為了解決這個(gè)問題,JavaScript允許主線程把二進(jìn)制數(shù)據(jù)直接轉(zhuǎn)移給子線程,但是一旦轉(zhuǎn)移,主線程就無法再使用這些二進(jìn)制數(shù)據(jù)了,這是為了防止出現(xiàn)多個(gè)線程同時(shí)修改數(shù)據(jù)的麻煩局面。這種轉(zhuǎn)移數(shù)據(jù)的方法,叫做Transferable Objects。

    如果要使用該方法,postMessage方法的最后一個(gè)參數(shù)必須是一個(gè)數(shù)組,用來指定前面發(fā)送的哪些值可以被轉(zhuǎn)移給子線程。

    worker.postMessage(arrayBuffer, [arrayBuffer]);

    8、同頁面的Web Worker

    通常情況下,子線程載入的是一個(gè)單獨(dú)的JavaScript文件,但是也可以載入與主線程在同一個(gè)網(wǎng)頁的代碼。假設(shè)網(wǎng)頁代碼如下:

    <!DOCTYPE html>      <body>          <script id="worker" type="app/worker">                addEventListener('message', function() {                  postMessage('Im reading Tech.pro');              }, false);        </script>      </body></html>

    我們可以讀取頁面的script,用worker來處理。

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

    這里需要把代碼當(dāng)作二進(jìn)制數(shù)據(jù)讀取,所以使用Blob接口。然后,這個(gè)二進(jìn)制對(duì)象轉(zhuǎn)為URL,再通過這個(gè)URL創(chuàng)建worker。

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

    部署事件監(jiān)聽代碼。

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

    最后啟動(dòng)worker。

    worker.postMessage('');

    整個(gè)頁面的代碼如下:

    <!DOCTYPE html>      <body>          <script id="worker" type="app/worker">                addEventListener('message', function() {                  postMessage('Work done!');              }, false);        </script>            <script>              (function() {                              var blob = new Blob([document.querySelector('#worker').textContent]);                              var url = window.URL.createObjectURL(blob);                              var worker = new Worker(url);                    worker.addEventListener('message', function(e) {                      console.log(e.data);                  }, false);                    worker.postMessage('');              })();        </script>      </body></html>

    可以看到,主線程和子線程的代碼都在同一個(gè)網(wǎng)頁上面。

    上面所講的Web Worker都是專屬于某個(gè)網(wǎng)頁的,當(dāng)該網(wǎng)頁關(guān)閉,worker就自動(dòng)結(jié)束。除此之外,還有一種共享式的Web Worker,允許多個(gè)瀏覽器窗口共享同一個(gè)worker,只有當(dāng)所有窗口關(guān)閉,它才會(huì)結(jié)束。這種共享式的Worker用SharedWorker對(duì)象來創(chuàng)建,因?yàn)檫m用場(chǎng)合不多,這里就省略了。

    贊(0)
    分享到: 更多 (0)
    網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)