中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

js javascript 實(shi)現多線程(cheng)

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

假如(ru)我們要(yao)(yao)執行(xing)(xing)一(yi)些(xie)耗(hao)時(shi)的(de)(de)(de)操作,比如(ru)加載一(yi)張很大(da)的(de)(de)(de)圖片,我們可(ke)(ke)能需(xu)要(yao)(yao)一(yi)個進度條來讓用(yong)(yong)戶進行(xing)(xing)等待,在(zai)等待的(de)(de)(de)過(guo)程(cheng)(cheng)中,整個js線程(cheng)(cheng)會被阻塞,后面(mian)的(de)(de)(de)代(dai)碼(ma)不(bu)能正(zheng)常(chang)運行(xing)(xing),這可(ke)(ke)能大(da)大(da)的(de)(de)(de)降低用(yong)(yong)戶體驗,這時(shi)候(hou)我們就(jiu)期望擁有一(yi)個工作線程(cheng)(cheng)來處理這些(xie)耗(hao)時(shi)的(de)(de)(de)操作。在(zai)傳統(tong)的(de)(de)(de)html時(shi)代(dai)是(shi)基本(ben)不(bu)可(ke)(ke)能實現的(de)(de)(de),而(er)現在(zai),我們擁有一(yi)種叫做worker的(de)(de)(de)東西。它(ta)是(shi)js里(li)的(de)(de)(de)一(yi)個類,而(er)我們只需(xu)要(yao)(yao)創建它(ta)的(de)(de)(de)實例就(jiu)可(ke)(ke)以使(shi)用(yong)(yong)它(ta)。

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>

下(xia)面是(shi)test22.js里(li)的代碼(ma),也(ye)就(jiu)是(shi)存(cun)在于worker線程(cheng)里(li)的代碼(ma)

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

運行起來我們會發現

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

雖然(ran)dialog的(de)(de)彈(dan)出(chu)會阻塞js引(yin)擎線(xian)程(cheng)(cheng)(cheng),但(dan)是(shi)并不(bu)影響worker線(xian)程(cheng)(cheng)(cheng)的(de)(de)運行,所(suo)以(yi),在我(wo)們點擊(ji)確(que)定后,只(zhi)是(shi)在js引(yin)擎線(xian)程(cheng)(cheng)(cheng)上更新(xin)了(le)新(xin)的(de)(de)內容,而數值(zhi)是(shi)一直在跑動的(de)(de),這(zhe)就說明worker線(xian)程(cheng)(cheng)(cheng)和(he)原本(ben)的(de)(de)js線(xian)程(cheng)(cheng)(cheng)互(hu)不(bu)影響.

那么既然互不影響,兩(liang)個線程(cheng)之間要怎(zen)么來(lai)聯(lian)系(xi)呢,答(da)案其(qi)實(shi)已經(jing)在(zai)代碼里(li)了,那就是onPostMessage 和 onmessage這兩(liang)個函(han)數,其(qi)中onPostMessage(data)的(de)(de)參數是你要傳遞的(de)(de)數據(ju)(ju),而onmessage是一個回調(diao)函(han)數,只有(you)在(zai)接受(shou)到數據(ju)(ju)時,onmessage會被回調(diao),onmessage有(you)一個隱藏(zang)的(de)(de)參數,那就是event,我們可(ke)以用event.data獲取到傳遞過來(lai)的(de)(de)數據(ju)(ju)來(lai)更新(xin)主線程(cheng)。

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

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

結(jie)果你(ni)會得到(dao)一條Error,告訴你(ni)找(zhao)不(bu)到(dao)document,或者document is undefined。所以我(wo)們盡(jin)量(liang)把需要的(de)東西都寫到(dao)主線程(cheng)里,而只把耗時的(de)操作寫到(dao)worker線程(cheng)里。

posted @ 2016-10-16 18:00  浩大王  閱讀(16091)  評論(0)    收藏  舉報