Javascript執(zhí)行機制 Javascript中的多線程 - WebWorker 專用型web worker 專用型worker與創(chuàng)建它的腳本連接在一起,它可以與其他的worker或是瀏覽器組件通信,但是他不能與DOM通信。專用的含義,就是這個線程一次只處理一個需求。專用線程在除了IE外的各種主流瀏覽器中都實現(xiàn)了,可以放心使用。 線程通信 發(fā)送JSON數(shù)據(jù) 處理錯誤 銷毀線程 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é)果。 ???console.log("Result:"? ?event.data); },?false); 個人覺得很麻煩,不如用onmessage直接。
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í)行),道理也很簡單。 ? 線程嵌套
? 共享型SharedWebWorker 在收到web worker腳本的首個消息之后,共享型web worker把一個事件處理程序附加到激活的端口上。一般情況下,處理程序會運行自己的postMessage()方法來把一個消息返回給調(diào)用代碼,接著端口的start()方法生成一個有效的消息進程。 ??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ā)送消息。 ? 線程中能做的事: 5.線程中可以用self獲取本線程的作用域。 ? 線程中不能做的事: ? 線程也是需要消耗資源的,而且使用線程也會帶來一定的復雜性,所以如果沒有充足的理由來使用額外的線程的話,那么就不要用它。 ? 來源:http://www./content-1-52001.html |
|