javascript-js實現多線程


在講之前,大家都知道js是基於單線程的,而這個線程就是瀏覽器的js引擎。
首先來看一下大家用的瀏覽器都具有那些線程吧。

假如我們要執行一些耗時的操作,比如加載一張很大的圖片,我們可能需要一個進度條來讓用戶進行等待,在等待的過程中,整個js線程會被阻塞,后面的代碼不能正常運行,這可能大大的降低用戶體驗,這時候我們就期望擁有一個工作線程來處理這些耗時的操作。在傳統的html時代是基本不可能實現的,而現在,我們擁有一種叫做worker的東西。它是js里的一個類,而我們只需要創建它的實例就可以使用它。

var worker = new Worker(js file path);

構造函數的參數填上你的js文件的路徑,這個js文件將會在瀏覽器新開的線程里運行,而與原先的js引擎的線程並不影響。
下面看個例子。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title></title>
	</head>
	<body>
		<input type="text" name="ipt" id="ipt" value="" />
		<button id="start">start</button>
		<button id="stop">stop</button>
		<button id="ale">alert</button>
		<script type="text/javascript">
			var ipt = document.getElementById("ipt");
			var stop = document.getElementById("stop");
			var start = document.getElementById("start");
			var ale = document.getElementById("ale");
			var worker = new Worker("js/test22.js");
			worker.onmessage = function(){
				ipt.value = event.data;
			};
			stop.addEventListener("click",function(){
				//用於關閉worker線程
				worker.terminate();
			});
			start.addEventListener("click",function(){
				//開起worker線程
				worker = new Worker("js/test22.js");
			});
			ale.addEventListener("click",function(){
				alert("i'm a dialog");
			});
		</script>
	</body>
</html>

下面是test22.js里的代碼,也就是存在於worker線程里的代碼

var i = 0;
function mainFunc(){
	i++;
	//把i發送到瀏覽器的js引擎線程里
	postMessage(i);
}
var id = setInterval(mainFunc,1000);

運行起來我們會發現

點擊確定后,它的數值並非2,而是一個比2更大的數

雖然dialog的彈出會阻塞js引擎線程,但是並不影響worker線程的運行,所以,在我們點擊確定后,只是在js引擎線程上更新了新的內容,而數值是一直在跑動的,這就說明worker線程和原本的js線程互不影響.

那么既然互不影響,兩個線程之間要怎么來聯系呢,答案其實已經在代碼里了,那就是onPostMessage 和 onmessage這兩個函數,其中onPostMessage(data)的參數是你要傳遞的數據,而onmessage是一個回調函數,只有在接受到數據時,onmessage會被回調,onmessage有一個隱藏的參數,那就是event,我們可以用event.data獲取到傳遞過來的數據來更新主線程。

使用worker線程應注意的是,所有js里集成的對象都在js線程里,而並非worker線程。
例如我們在worker線程里寫上:

var a = document.getElementById("a");

結果你會得到一條Error,告訴你找不到document,或者document is undefined。所以我們盡量把需要的東西都寫到主線程里,而只把耗時的操作寫到worker線程里。


免責聲明!

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



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