(吐槽:瀏覽器js終於進入多執行緒時代!)
以前利用settimeout、setinterval等方式的多執行緒,是偽多執行緒,本質上是一種在單執行緒中進行佇列執行的方式。自從html5 web worker出現,js真正進入了多執行緒程式設計時期,現在就開始js的「真·多執行緒」秘籍修煉吧!
最近因為工作中的需要,使用了html5的web worker,之前一直對worker一知半解。直到看到ibm上的一篇博文(知識不是完全有效,可以當作參考),才對worker有了基本概念。
worker分類
worker分為專用線程和共享執行緒。專用線程只能在當前頁面中訪問到。而如果要多個頁面訪問同乙個worker,就要使用共享執行緒,但前提是這幾個頁面是同域的。
worker基本用法
一、專用線程
1、在瀏覽器執行緒中(即插入頁面的js**,內聯、外鏈的js**都可以):
1var worker=new worker("testworker.js");
23 worker.onmessage=function
(event);
78 worker.onerror=function
(event);
1213 worker.postmessage("some data");/*
向worker執行緒傳送資料
*/
worker一直處於監聽狀態,要釋放這個執行緒必須在瀏覽器執行緒呼叫worker.terminate();以釋放資源。
2、在worker執行緒**中:
1this.onmessage=function
(event);
在worker執行緒中,如果不用接收瀏覽器執行緒發來資料或者瀏覽器執行緒不傳送資料,則可以直接執行處理,最後this.postmessage(/*data*/)就行了。
在上例中,this指執行緒物件,所以最好的用法是在第一行**的前面加上「var thread=this;」,然後就可以在任何地方使用thread.postmessage和thread.onmessage方法。worker執行緒中的**變成:
1var thread=this
;2 thread.onmessage=function
(event);
二、共享執行緒
1、瀏覽器執行緒中:
1var sharedworker=new sharedworker("sharedworker.js");
23 worker.onerror=function
(e);
7 worker.port.onmessage=function
(event);
10 worker.port.onerror=function
(e);
1415 worker.port.start();/*
必須執行start以開始連線
*/
在瀏覽器執行緒中,通訊是通過worker的port物件進行的,每乙個頁面的port是不同的,具有唯一性。最關鍵的一點是start(),這個函式表示開始連線shared worker,連線成功時,worker執行緒將增加乙個連線數。
在同域下的其他頁面呼叫此shared worker,**結構與此相同,只是處理資料的邏輯可能不同。
2、worker執行緒中:
1var thread=this
,2 connectioncount=0;
3 thread.onconnect=function
(e) ;
10 connectioncount++;
11 };
在worker**中,在onconnect**函式中獲取請求連線者的連線物件port,然後就可以通過這個port與請求者通訊。
在這裡,可以把port快取起來,以後worker可以隨時主動postmessage給瀏覽器特定的頁面執行緒。這需要頁面傳送自己的「全域性唯一特徵碼」供worker識別。
生命週期
專用線程的生命週期與頁面的生命週期一致,可以使用worker.terminate()關閉釋放執行緒。
共享執行緒的生命週期與其連線數相關,當連線數為0時,將自動關閉釋放。如果需要關閉當前頁面的連線,可以呼叫worker.port.close(),worker執行緒中的連線數將減少乙個。關閉頁面也和呼叫worker.port.close具有同樣的影響。
尾記1、worker也和伺服器端的多執行緒一樣,建立、銷毀開銷較大。所以,worker只應該用於耗時操作,例如複雜、長時間的運算。
2、worker不能訪問dom及頁面相關物件如window document,這也在一定程度上限制了worker的應用,也不能在worker中建立worker。
3、worker中可以使用xmlhttprequest,可以自己寫乙個包裝http請求的物件到worker執行緒**中,或者找個開源的http庫。使用開源庫需要解決如何引入的問題,還沒有研究。
4、可以動態建立worker**。提供思路,具體怎麼做的忘了:) ------------ 將需要執行的**轉換為字串,再轉換為二進位制的blob物件,再使用window.url.createobjecturl建立動態url,引數是blob物件,然後將這個動態url傳入worker的建構函式,作為第乙個引數。這種一般是用在專用線程上。例子如下。
1var doworkbyhtml5worker = (function
() ;
11clearblob();
12 } else
if(blob) ,
18 getblob: function
() ,
21 clear: function
() 24}25
}2627return
39 worker = new
worker(urlcontext.createobjecturl(blobbuilder.getblob()));
40 worker.onmessage = function
(e) ;46}
47};
48 })();
使用:
1/*基本演示*/2
doworkbyhtml5worker.do(
3function
(),6
null,7
function
(data)
11);
1213
/*帶引數演示
*/14
doworkbyhtml5worker.do(
15function
(obj)";
17},
18 ,
19function
(data)"
*/22}23
);24
25/*
傳入字串型執行函式
*/26
var dosomething=(function
()).tostring();
29/*
或者:var dosomething="function()";
*/30
doworkbyhtml5worker.do(
31dosomething,
32null,33
function
(data)
37 );
參考:1、菜鳥教程
2、ibm博文
3、w3c文件
學HTML5需要注意哪些問題
要怎麼去學html5?學習的方式有很多,可以自學,也可以找專門的html5培訓機構去學習,具體選擇哪種方式,是要看哪種學習方式自己能接受。總體來講就是h5涵蓋了所有基於移動社交商務場景中的內容載體形式。pc時代的網頁能做什麼,html5在移動端就能做什麼。看起來,html5是有著不少優勢,這也是h5...
HTML5邊玩邊學(1) 畫布
一 標籤 html5 引入了乙個新的 標籤,這個標籤所代表的區域就好象一塊畫布,你的所有圖形繪製最後都要在這塊畫布上呈現。有了這個標籤,瀏覽器的圖形表現力被極大的提公升,flash 和 silverlight 有沒有感到威脅呢?標籤的用法非常簡單,如下 code highlighting produ...
HTML5邊玩邊學(1) 畫布
一 標籤 html5 引入了乙個新的 標籤,這個標籤所代表的區域就好象一塊畫布,你的所有圖形繪製最後都要在這塊畫布上呈現。有了這個標籤,瀏覽器的圖形表現力被極大的提公升,flash 和 silverlight 有沒有感到威脅呢?google聲稱chrome7瀏覽器將提速60倍 標籤的用法非常簡單,如...