【HTML5】webworker簡介


webworker的作用

讓web應用程序具備多線程處理能力,常用來處理一些比較耗時的任務。假設我們的應用上有個純前端實現的馬賽克濾鏡,我們知道圖像處理,尤其是大圖片的處理通常是比較耗費時的,隨時都有可能讓你的頁面卡個幾秒,這期間UI線程會被阻塞,這意味着用戶需要對着一個無法進行任何交互的頁面抓狂,這是無法容忍的。這個時候,webworker就發揮它的用處了,圖像處理神馬的后台悄悄進行就行了,用戶可以繼續瀏覽器美圖神馬的(奸笑),時間到,打了馬賽克的妹子圖片就呈現在用戶面前了

 

簡單例子

下面的demo涉及兩個文件,分別是demo.html、worker.js。代碼很簡單,但已經包含了webworker最重要的幾個內容,細節在后面再展開:

  1. worker創建:new Worker(XX)
  2. 消息發送:postMessage
  3. worker事件:消息接收(message)、出錯處理(error)
  4. worker終止:terminate

demo.html里面的代碼:

var worker = new Worker('worker.js');
worker.onmessage = function(evt){
    alert('消息收到啦:'+ evt.data);
    worker.terminate();
};
worker.onerror = function(e){
    alert('demo出錯了!出錯原因是:' + e.message);
    worker.terminate();
};
worker.postMessage('這是webworker的demo!');

worker.js里面的代碼:

this.onmessage = function(evt){
    postMessage(evt.data +'--worker.js里的附加信息');
};

demo演示內容:

  1. demo.html里創建一個worker WW加載worker.js,並向其發送消息:這是'webworker的demo!'
  2. worker.js 收到W傳給它的消息,並在該消息末尾加上'--worker.js里的附加信息'后,再回傳給W
  3. W收到worker.js回傳的消息,彈窗顯示,然后把自己給終止掉

最終你會看到

消息收到啦:這是webworker的demo!--worker.js里的附加信息

 

常用API等簡單介紹

1. worker創建

注意:引號里的url地址可以為絕對地址,或相對地址,但必須同源

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

2. 常用API

possMessage(data)

data理論上可以為任意值,但保險起見最好還是傳字符串,接收方需注冊message事件老接收消息,如demo.html中

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

terminate()

終止worker,此后無法再利用其進行消息傳遞等。需要注意:worker不會自行終止,一旦terminate,無法重新啟用,只能另行創建。如demo.html中

worker.terminate();

3. 事件

message

一旦有消息發送,則會觸發。消息的發送是雙向的,消息的內容可通過data獲取,如demo.html中,evt.data即為worker.js中傳遞過來的消息內容:

worker.onmessage = function(evt){
    alert('消息收到啦:'+ evt.data);
    worker.terminate();
};

error

出錯處理,比如worker.js中出現語法錯誤、運行時錯誤之類的,就會觸發,錯誤信息可通過e.message獲得,如demo.html中

worker.onerror = function(e){
    alert('demo出錯了!出錯原因是:' + e.message);
    worker.terminate();
};

 

worker的上下文

剛剛接觸web worker的童鞋,對於這點可能有些疑惑。我們可以先用下面這個小小的例子簡單說明一下。還是之前的worker.js,只不過在最開頭的時候加上了一句alert('hello world');

alert('hello'); //額外添加的語句
this.onmessage = function(evt){
    postMessage(evt.data +'--worker.js里的附加信息');
};

於是,你會看到下面的彈窗內容

demo出錯了!出錯原因是:Uncaught ReferenceError: window is not defined

從上面的出錯提示可以猜想:worker.js執行的上下文,與demo.html執行時的上下文並不相同,最頂層的對象的對象並不是window,無法訪問window、與window相關的DOM API,但是可以與setTimeout、setInterval等協作。
woker.js執行的全局上下文,是個叫做WorkerGlobalScope的東東,它具有屬性/方法:

self

指向WorkerGlobalScope

inmoprScripts(XX[,XX, XX…])

加載外部腳本文件,理論上是按照加載它們的順序執行(僅僅是理論上),且執行上下文與當前執行上下文一致,比如在worker.js里面

importScripts('subworker.js');
importScripts('a.js', 'b.js', 'c.js');

那么理論上,subworker.js、a.js、b.js、c.js應該是hi順序執行的,這里就不舉具體例子了。

close()

關閉當前線程,與terminate作用類似

location

返回當前worker的location信息,location.href為當前worker創建時指向的文件絕對路徑

setTimeout/setInterval

沒什么好介紹的

子worker的創建

可在當前woker環境下,通過new Worker(XX)方式創建子worker,需要注意的有以下幾點:

  1. 子worker的路徑必須與父網頁同源
  2. 子worker的路徑相對於父worker解析,而不是父網頁
  3. webkit(chrome 25,safari 6)內核的瀏覽器尚不支持子worker,無力吐槽

 

需要注意的坑

前端科普文必然有的一塊內容,腫么突然有點心酸~~Fraky大大已經總結了不少,就偷懶下了,鏈接如下可猛點擊:http://www.cnblogs.com/_franky/archive/2010/11/23/1885773.html

 

待解決

  1. 調試問題:chrome最新版本也仍不支持子線程調試??(已支持,開發者工具-source-workers)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM