欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

再談JavaScript線程

 更新時間:2015年07月10日 11:55:36   投稿:hebedich  
繼上篇討論了一些關于JavaScript線程的知識,我們不妨回過頭再看看,是不是JavaScript就不能多線程呢?看下面一段很簡單的代碼(演示用,沒考慮兼容問題):

代碼判斷一:

<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í)行之,不出意外的話所有瀏覽器都會卡死,因為上面的for循環(huán)次數(shù)太多了,非常耗費CPU資源,而基于JavaScript單線程的事實,瀏覽器UI渲染被掛起而導致假死。

       現(xiàn)在問題來了,我就是想要實現(xiàn)上述代碼,怎么辦?

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

代碼片段二:

<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>

 通過該類庫提供的create方法可以創(chuàng)建一個“新線程”。另外,給script標簽的type屬性設置為 text/x-script.multithreaded-js 也可以實現(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
    針對以上瀏覽器卡死這種糟糕的用戶體驗,HTML5怎么會熟視無睹呢?

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

代碼片段四:

主頁面:

<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;//獲得當前時間戳
       var worker=new Worker("fibonacci.js");//創(chuàng)建WebWorker對象,并傳遞在新線程中將要執(zhí)行的腳本的路徑
       worker.onmessage=function(e){ //監(jiān)聽從新線程發(fā)送過來的數(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));//向主頁面發(fā)送數(shù)據(jù)
}

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

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

    worker.postMessage(36);

    worker.postMessage(36);

    worker.postMessage(36);

       因為此時只有一個WebWorker實例,postMessage會順序執(zhí)行而不是異步執(zhí)行,就不能充分發(fā)揮它的性能了??梢酝ㄟ^創(chuàng)建多個WebWorker實例來發(fā)送數(shù)據(jù)。

        需要注意的幾點事項有:

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

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

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

相關文章

最新評論