HTML5 Web Worker(讀書筆記)

最近看了《HTML5與CSS3權威指南》,瞭解下Web Worker,以下爲書中第十章內容

(一)基礎知識

JavaScript創建的Web程序,處理都是在單線程內執行,花費時間較長,程序處於長時間沒有響應的狀態。例如下面例子:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<script type="text/javascript">
function calculate(){
   var num=parseInt(document.getElementById("num").value,10);
   var result=0;
   for(var i=0;i<=num;i++){
    result+=i;
   } 
   alert("結果爲"+result);
}
</script>
</head>
<body>
<h1>求和</h1>
輸入數值:<input type="text" id="num">
<button οnclick="calculate()">計算</button>
</body>
</html>

上述例子中,當輸入值較大,會彈出警告框

HTML5 新增一個Web Worker API。用戶可以容易地創建在後臺的線程,將耗費較長時間的處理交給後臺,用戶在前臺頁面中執行的操作就完全沒有影響了。

1)創建後臺程序

var worker=new Worker("worker.js");
後臺程序線程中不能訪問窗口對象和頁面,在後臺線程的腳本文件中使用document和window對象,會引起錯誤。

2)接收後臺線程之中的消息

worker.onmessage=function(event)
{
     //處理收到的消息
}
3)使用postMessage向後臺線程發送消息

worker.postMessage(message);
發送的消息可以是文本數據,任何javascript對象(需要使用JSON的stringify方法將其轉換爲文本數據)

Worker對象的onmessage事件句柄和postMessage事件句柄方法在後臺線程內部進行消息的接收和發送

使用WebWorkers重寫上例,如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<script type="text/javascript">
//創建執行運算的線程
var worker=new Worker("SumCalculate.js")
//接受從線程中傳出的計算結果
worker.onmessage=function(event){
    //消息文本放置在data屬性中,可以是任何javascript對象
    alert("結果爲:"+event.data);
};

function calculate(){
    var num=parseInt(document.getElementById("num").value,10);
    //將數值傳給線程
    worker.postMessage(num);
}
</script>
</head>
<body>
<h1>求和</h1>
輸入數值:<input type="text" id="num">
<button οnclick="calculate()">計算</button>
</body>
</html>
其中,線程代碼單獨寫在SumCalculate.js中

onmessage=function(event){
   var num=event.data;
   var result=0;
   for(var i=0;i<num;i++){
    result+=i;
   } 
   //向線程創建源送回消息
   postMessage(result);
}

(二)與線程進行數據的交互以及線程嵌套

使用後臺線程不能訪問頁面和窗口對象,但後臺線程可以和頁面之間進行數據交互。下面爲一個從隨機生成的數字中抽取3的倍數並顯示:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<script type="text/javascript">
//創建執行運算的線程
var worker=new Worker("worker1.js");
worker.postMessage("");
//接受從線程中取得的計算結果
worker.onmessage=function(event){
   if(event.data!=""){
    var j;  //行號
    var k;  //列號
    var tr;
    var td;
    var intArray=event.data.split(";");
    var table=document.getElementById("table");
    for(var i=0;i<intArray.length;i++){
        j=parseInt(i/10,10);
        k=i%10;
        if(k==0){ //該行不存在
            //添加行
            tr=document.createElement("tr");
            tr.id="tr"+j;
            table.appendChild(tr);        
        } else{ //該行已經存在
            //獲取該行
            tr=document.getElementById("tr"+j);
        }
        //添加列
        td=document.createElement("td");
        tr.appendChild(td);
        //設置該列的內容
        td.innerHTML=intArray[j*10+k];
        //設置該列背景色
        td.style.backgroundColor="blue";
        td.style.color="white";
        td.width="30";       
    }
   }
};
</script>
</head>
<body>
<h1>從隨機生成的數字中抽取3的倍數並顯示比例</h1>
<table id="table"></table>
</body>
</html>

主線程worker1.js的代碼爲

onmessage=function(event){
    var intArray=new Array(100);  //隨機數組
     //生成100個隨機數
     for(var i=0;i<100;i++){
        intArray[i]=parseInt(Math.random()*100);
        }
        var worker;
        //創建子線程
        worker=new Worker("worker2.js");
        //把隨機數組提交給子線程進行挑選工作
        worker.postMessage(JSON.stringify(intArray));
        worker.onmessage=function(event){
            //挑選結果返回主頁面
            postMessage(event.data);
        }
}

子線程worker2.js的代碼爲

onmessage=function(event){
    //還原整數數組
    var intArray=JSON.parse(event.data);
    var returnStr="";
    for(var i=0;i<intArray.length;i++){
        //能否被3整除
        if(parseInt(intArray[i])%3==0){
            if(returnStr!="")
                returnStr+=";";
                //將能被3整除的數字拼接成字符串
                returnStr+=intArray[i];
        }     
    }
       //返回字符串
        postMessage(returnStr);
        //關閉子線程
        close();
}
注:子線程向發送源發送回消息後,最好使用close關閉子線程,如果子線程不在使用。

(三)子線程與子線程之間的數據交互,大致步驟如下:

1)先創建發送數據的子線程

2)執行子線程任務,把要傳遞的數據發送給主線程

3)在主線程接受到子線程傳遞迴的消息時,創建接收數據的子線程,然後把發送數據的子線程中返回的消息傳遞給接收數據的子線程

4)執行接收數據子線程中的代碼

以上爲HTML5 Web Worker學習的總結




































發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章