乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       印度阿三17 2018-10-14

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

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

      專(zhuān)用型web worker

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

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

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

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

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

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

      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));
      };

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

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

      個(gè)人覺(jué)得很麻煩,不如用onmessage直接。


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

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

      ??????導(dǎo)入以后,可以直接使用這些文件中的方法。看一個(gè)網(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方法解決資源預(yù)加載的問(wèn)題(瀏覽器預(yù)先加載資源,而不會(huì)對(duì)資源進(jìn)行解析和執(zhí)行),道理也很簡(jiǎn)單。

      ?

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


      同步問(wèn)題
      ??????Worker沒(méi)有鎖的機(jī)制,多線程的同步問(wèn)題只能靠代碼來(lái)解決(比如定義信號(hào)變量)。

      ?

      共享型SharedWebWorker
        共享型web worker主要適用于多連接并發(fā)的問(wèn)題。因?yàn)橐幚矶噙B接,所以它的API與專(zhuān)用型worker稍微有點(diǎn)區(qū)別。除了這一點(diǎn),共享型web worker和專(zhuān)用型worker一樣,不能訪問(wèn)DOM,并且對(duì)窗體屬性的訪問(wèn)也受到限制。共享型web worker也不能跨越通信。
        頁(yè)面腳本可以與共享型web worker通信,然而,與專(zhuān)用型web worker(使用了一個(gè)隱式的端口通信)稍微有點(diǎn)不同的是,通信是顯式的通過(guò)使用一個(gè)端口(port)對(duì)象并附加上一個(gè)消息事件處理程序來(lái)進(jìn)行的。

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

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

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

      ?

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

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

      ?

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

      ?

      線程也是需要消耗資源的,而且使用線程也會(huì)帶來(lái)一定的復(fù)雜性,所以如果沒(méi)有充足的理由來(lái)使用額外的線程的話,那么就不要用它。

      ?

      來(lái)源:http://www./content-1-52001.html

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

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多