日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

【轉(zhuǎn)載】HTML5之Javascript多線程

 印度阿三17 2018-10-14

Javascript執(zhí)行機制
??????在HTML5之前,瀏覽器中JavaScript的運行都是以單線程的方式工作的,雖然有多種方式實現(xiàn)了對多線程的模擬(例如:Javascript 中的 setinterval 方法,setTimeout 方法等),但是在本質(zhì)上程序的運行仍然是由 JavaScript 引擎以單線程調(diào)度的方式進行的。在 HTML5 中引入的工作線程使得瀏覽器端的 Javascript 引擎可以并發(fā)地執(zhí)行 Javascript 代碼,從而實現(xiàn)了對瀏覽器端多線程編程的良好支持。

Javascript中的多線程 - WebWorker
??????HTML5 中的 Web Worker 可以分為兩種不同線程類型,一個是專用線程 Dedicated Worker,一個是共享線程 Shared Worker。兩種類型的線程各有不同的用途。

專用型web worker

  專用型worker與創(chuàng)建它的腳本連接在一起,它可以與其他的worker或是瀏覽器組件通信,但是他不能與DOM通信。專用的含義,就是這個線程一次只處理一個需求。專用線程在除了IE外的各種主流瀏覽器中都實現(xiàn)了,可以放心使用。
創(chuàng)建線程
??????創(chuàng)建worker很簡單,只要把需要在線程中執(zhí)行的JavaScript文件的文件名傳給構(gòu)造函數(shù)就可以了。

線程通信
??????在主線程與子線程間進行通信,使用的是線程對象的postMessage和onmessage方法。不管是誰向誰發(fā)數(shù)據(jù),發(fā)送發(fā)使用的都是postMessage方法,接收方都是使用onmessage方法接收數(shù)據(jù)。postMessage只有一個參數(shù),那就是傳遞的數(shù)據(jù),onmessage也只有一個參數(shù),假設為event,則通過event.data獲取收到的數(shù)據(jù)。

發(fā)送JSON數(shù)據(jù)
??????JSON是JS原生支持的東西,不用白不用,復雜的數(shù)據(jù)就用JSON傳送吧。例如:

postMessage({'cmd':?'init',?'timestamp':?Date.now()});

處理錯誤
??????當線程發(fā)生錯誤的時候,它的onerror事件回調(diào)會被調(diào)用。所以處理錯誤的方式很簡單,就是掛接線程實例的onerror事件。這個回調(diào)函數(shù)有一個參數(shù)error,這個參數(shù)有3個字段:message - 錯誤消息;filename - 發(fā)生錯誤的腳本文件;lineno - 發(fā)生錯誤的行。

銷毀線程
??????在線程內(nèi)部,使用close方法線程自己銷毀自己。在線程外部的主線程中,使用線程實例的terminate方法銷毀線程。

HTML代碼:

<script?type="text/javascript">
??onload?=?function(){
??????var?worker?=?new?Worker('fibonacci.js');??
??????worker.onmessage?=?function(event)?{
????????console.log("Result:"? ?event.data);
??????};
??????worker.onerror?=?function(error)?{
????????console.log("Error:"? ?error.message);
??????};
??????worker.postMessage(40);
??}??
??</script>
腳本文件fibonacci.js代碼: //fibonacci.js
var?fibonacci?=?function(n)?{
????return?n?<?2???n?:?arguments.callee(n?-?1)? ?arguments.callee(n?-?2);
};
onmessage?=?function(event)?{
????var?n?=?parseInt(event.data,?10);
????postMessage(fibonacci(n));
};

把它們放到相同的目錄,運行頁面文件,查看控制臺,可以看到運行的結(jié)果。
這里還有一點,在主線程中,onmessage事件可以使用另外一種方式掛接:

worker.addEventListener('message',?function(event)?{
???console.log("Result:"? ?event.data);
},?false);

個人覺得很麻煩,不如用onmessage直接。


使用其他腳本文件
??????工作線程可以使用全局方法importScripts來加載和使用其他的域內(nèi)腳本文件或者類庫。例如下面都是合法的使用方式:

importScripts();????????????????????????
importScripts('foo.js');????????????????
importScripts('foo.js',?'bar.js');??????

??????導入以后,可以直接使用這些文件中的方法??匆粋€網(wǎng)上的小例子:

?
?importScripts('math_utilities.js');?
?
?onmessage?=?function?(event)?
?{?
???var?first = event.data.first;?
???var?second = event.data.second;?
???calculate(first,second);?
?};?
?
?function?calculate(first,second)?{?
????//do?the?calculation?work?
???var?common_divisor=divisor(first,second);?
???var?common_multiple=multiple(first,second);?
???postMessage("Work?done!?"? ?
??????"The?least?common?multiple?is?" common_divisor?? ??????"?and?the?greatest?common?divisor?is?" common_multiple);?
?}?

??????網(wǎng)上也有網(wǎng)友想到了利用這里的importScripts方法解決資源預加載的問題(瀏覽器預先加載資源,而不會對資源進行解析和執(zhí)行),道理也很簡單。

?

線程嵌套
??????在工作線程中還可以在創(chuàng)建子線程,各種操作還是一樣的。


同步問題
??????Worker沒有鎖的機制,多線程的同步問題只能靠代碼來解決(比如定義信號變量)。

?

共享型SharedWebWorker
  共享型web worker主要適用于多連接并發(fā)的問題。因為要處理多連接,所以它的API與專用型worker稍微有點區(qū)別。除了這一點,共享型web worker和專用型worker一樣,不能訪問DOM,并且對窗體屬性的訪問也受到限制。共享型web worker也不能跨越通信。
  頁面腳本可以與共享型web worker通信,然而,與專用型web worker(使用了一個隱式的端口通信)稍微有點不同的是,通信是顯式的通過使用一個端口(port)對象并附加上一個消息事件處理程序來進行的。

  在收到web worker腳本的首個消息之后,共享型web worker把一個事件處理程序附加到激活的端口上。一般情況下,處理程序會運行自己的postMessage()方法來把一個消息返回給調(diào)用代碼,接著端口的start()方法生成一個有效的消息進程。
??????看網(wǎng)上能找到的的唯一個例子:創(chuàng)建一個共享線程用于接收從不同連接發(fā)送過來的指令,然后實現(xiàn)自己的指令處理邏輯,指令處理完成后將結(jié)果返回到各個不同的連接用戶。
HTML代碼:

<script>?
??var?worker?=?new?SharedWorker('sharedworker.js');?
??var?log?=?document.getElementByIdx_x_x_x_x('response_from_worker');?
??worker.port.addEventListener('message',?function(e)?{?
??//log?the?response?data?in?web?page?
??log.textContent?=e.data;?
??},?false);?
??worker.port.start();?
??worker.port.postMessage('ping?from?user?web?page..');?
??
??//following?method?will?send?user?input?to?sharedworker?
??function?postMessageToSharedWorker(input)?
??{?
??//define?a?json?object?to?construct?the?request?
??var?instructions={instruction:input.value};?
??worker.port.postMessage(instructions);?
??}?
??</script>?
?

?腳本文件代碼:

?//?創(chuàng)建一個共享線程用于接收從不同連接發(fā)送過來的指令,指令處理完成后將結(jié)果返回到各個不同的連接用戶。
?var?connect_number?=?0;?
?
?onconnect?=?function(e)?{?
??connect_number?=connect_number ?1;?
??//get?the?first?port?here?
??var?port?=?e.ports[0];?
??port.postMessage('A?new?connection!?The?current?connection?number?is?'?
?? ?connect_number);?
??port.onmessage?=?function(e)?{?
???//get?instructions?from?requester?
???var?instruction=e.data.instruction;?
???var?results=execute_instruction(instruction);?
????port.postMessage('Request:?' instruction '?Response?' results?
?????? '?from?shared?worker...');?
??};?
?};?
?function?execute_instruction(instruction)?
?{?
?var?result_value;?
?//implement?your?logic?here?
?//execute?the?instruction...?
?return?result_value;
?}?

??????在上面的共享線程例子中,在主頁面即各個用戶連接頁面構(gòu)造出一個共享線程對象,然后定義了一個方法 postMessageToSharedWorker 向共享線程發(fā)送來之用戶的指令。同時,在共享線程的實現(xiàn)代碼片段中定義 connect_number 用來記錄連接到這個共享線程的總數(shù)。之后,用 onconnect 事件處理器接受來自不同用戶的連接,解析它們傳遞過來的指令。最后,定義一個了方法 execute_instruction 用于執(zhí)行用戶的指令,指令執(zhí)行完成后將結(jié)果返回給各個用戶。

??????這里我們并沒有跟前面的例子一樣使用到了工作線程的 onmessage 事件處理器,而是使用了另外一種方式 addEventListener。實際上,前面已經(jīng)說過,這兩種的實現(xiàn)原理基本一致,只是在這里有些稍微的差別,如果使用到了 addEventListener 來接受來自共享線程的消息,那么就要先使用 worker.port.start() 方法來啟動這個端口。之后就可以像工作線程的使用方式一樣正常的接收和發(fā)送消息。

?

線程中能做的事
1.能使用setTimeout(), clearTimeout(), setInterval(),clearInterval()等函數(shù)。
2.能使用navigator對象。
3.能使用XMLHttpRequest來發(fā)送請求。
4.可以在線程中使用Web Storage。

5.線程中可以用self獲取本線程的作用域。

?

線程中不能做的事
1.線程中是不能使用除navigator外的DOM/BOM對象,例如window,document(想要操作的話只能發(fā)送消息給worker創(chuàng)建者,通過回調(diào)函數(shù)操作)。
2.線程中不能使用主線程中的變量和函數(shù)。
3.線程中不能使用有"掛起"效果的操作命令,例如alert等。
4.線程中不能跨域加載JS。

?

線程也是需要消耗資源的,而且使用線程也會帶來一定的復雜性,所以如果沒有充足的理由來使用額外的線程的話,那么就不要用它。

?

來源:http://www./content-1-52001.html

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多