国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

再談JavaScript線程

2019-11-20 12:04:08
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

代碼判斷一:

<div id="div">  click me</div><script>  var div=document.getElementById("div");  div.addEventListener('click',function(){   alert('You have clicked me!');  });  for(var i =0; i<999999999;i++){   console.log(i);  }</script>

執(zhí)行之,不出意外的話所有瀏覽器都會(huì)卡死,因?yàn)樯厦娴膄or循環(huán)次數(shù)太多了,非常耗費(fèi)CPU資源,而基于JavaScript單線程的事實(shí),瀏覽器UI渲染被掛起而導(dǎo)致假死。

       現(xiàn)在問(wèn)題來(lái)了,我就是想要實(shí)現(xiàn)上述代碼,怎么辦?

Concurrent.Thread.js
       該類庫(kù)實(shí)質(zhì)上還是使用setTimeout來(lái)實(shí)現(xiàn)一個(gè)“假的多線程”。在HTML5 WebWorker問(wèn)世之前是一個(gè)很好的選擇。比如我們要實(shí)現(xiàn)上述“代碼片段一”,可以這樣寫(點(diǎn)我下載類庫(kù)):

代碼片段二:

<div id="div">  click me</div><script src="Concurrent.Thread.js"></script><script>  Concurrent.Thread.create(function(){    var div=document.getElementById("div");    div.addEventListener('click',function(){     alert('You have clicked me!');    });    for(var i =0; i<9999999;i++){     console.log(i);    }  });</script>

 通過(guò)該類庫(kù)提供的create方法可以創(chuàng)建一個(gè)“新線程”。另外,給script標(biāo)簽的type屬性設(shè)置為 text/x-script.multithreaded-js 也可以實(shí)現(xiàn)同樣的效果:

代碼片段三:

<div id="div">  click me</div><script src="Concurrent.Thread.js"></script><script type="text/x-script.multithreaded-js">    var div=document.getElementById("div");    div.addEventListener('click',function(){     alert('You have clicked me!');    });    for(var i =0; i<9999999;i++){     console.log(i);    }</script>

WebWorker
    針對(duì)以上瀏覽器卡死這種糟糕的用戶體驗(yàn),HTML5怎么會(huì)熟視無(wú)睹呢?

     下面我們用經(jīng)典的斐波那契數(shù)列來(lái)做測(cè)試:

代碼片段四:

主頁(yè)面:

<div id="div"></div><script>  window.onload=function(){     var div=document.getElementById("div");     if(typeof(Worker)!=="undefined"){//在創(chuàng)建WebWorker之前,先判斷瀏覽器是否支持        console.log("Start calculating....");       var time1= new Date()*1;//獲得當(dāng)前時(shí)間戳       var worker=new Worker("fibonacci.js");//創(chuàng)建WebWorker對(duì)象,并傳遞在新線程中將要執(zhí)行的腳本的路徑       worker.onmessage=function(e){ //監(jiān)聽從新線程發(fā)送過(guò)來(lái)的數(shù)據(jù)         div.innerHTML=e.data;         var time2=new Date()*1;         console.log("time spend:"+(time2-time1)+"ms");       }               worker.postMessage(36);//向新線程發(fā)送數(shù)據(jù)     }else{       alert("Your browser do not support WebWoker");     }  }</script>fibonacci.js:var fibonacci=function (n){  return n<3?n:(arguments.callee(n-1)+arguments.callee(n-2));}onmessage=function(e){  var num=parseInt(e.data,10);  postMessage(fibonacci(num));//向主頁(yè)面發(fā)送數(shù)據(jù)}

基本的使用方法已在代碼中做注釋了,查看控制臺(tái),可以看見很快就打印出執(zhí)行時(shí)間了。所以我們得出的結(jié)論是:WebWorker適合在前端執(zhí)行復(fù)雜的大量的計(jì)算。需要注意的是,WebWorker不支持跨域,本地測(cè)試還是用http協(xié)議,不要用file協(xié)議,否則不能創(chuàng)建Worker對(duì)象而報(bào)腳本錯(cuò)誤 。

        如果我們需要連續(xù)執(zhí)行多個(gè)postMessage操作,最好不要work.postMessage一直寫,像這樣:

    worker.postMessage(36);    worker.postMessage(36);    worker.postMessage(36);

       因?yàn)榇藭r(shí)只有一個(gè)WebWorker實(shí)例,postMessage會(huì)順序執(zhí)行而不是異步執(zhí)行,就不能充分發(fā)揮它的性能了。可以通過(guò)創(chuàng)建多個(gè)WebWorker實(shí)例來(lái)發(fā)送數(shù)據(jù)。

        需要注意的幾點(diǎn)事項(xiàng)有:

        1、我們觀察到WebWorker通過(guò)接受一個(gè)url來(lái)創(chuàng)建一個(gè)worker,而jsonp的實(shí)現(xiàn)原理就是通過(guò)動(dòng)態(tài)插入script標(biāo)簽加載數(shù)據(jù),那我們嘗試用WebWorker來(lái)實(shí)現(xiàn)同樣的事情不是更好嗎?因?yàn)閃ebWorker是多線程的,沒有阻塞,豈不美哉?但實(shí)際上經(jīng)過(guò)實(shí)驗(yàn),我們發(fā)現(xiàn)WebWorker表現(xiàn)并不如意。所以這并不是它擅長(zhǎng)的事,我們還是不要讓它越俎代庖的好。

        2、WebWorker在接受其他來(lái)源信息的時(shí)候,其實(shí)也給站點(diǎn)的安全帶來(lái)了隱患,如果接收不明來(lái)源的腳本信息,可能會(huì)導(dǎo)致XSS注入攻擊。所以這點(diǎn)需要防范,其實(shí)我們上面例子中使用innerHTML是不安全的,可以使用innerText或現(xiàn)代瀏覽器提供的textContent來(lái)替代,以過(guò)濾掉html標(biāo)簽。

  今天比較累了,想睡覺了,先寫這么多吧。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 贡山| 盘锦市| 澳门| 大安市| 额敏县| 株洲市| 睢宁县| 芒康县| 紫阳县| 常德市| 嘉定区| 深州市| 璧山县| 瑞金市| 射阳县| 禄丰县| 峨山| 盐山县| 宜昌市| 开化县| 武宣县| 杨浦区| 新干县| 信丰县| 黑龙江省| 临泽县| 北辰区| 崇文区| 连南| 怀集县| 安龙县| 博白县| 颍上县| 高碑店市| 伊金霍洛旗| 美姑县| 乌兰察布市| 灌阳县| 剑河县| 安化县| 茶陵县|