JavaScript被設計爲在單線程環境中運行,這意味著多個腳本不能同時運行。考慮這樣一種情況:您需要處理UI事件、查詢和處理大量API數據以及操作DOM。
JavaScript會在CPU利用率高的情況下掛起瀏覽器。讓我們舉一個簡單的例子,JavaScript會經歷一個大循環&負;
<!DOCTYPE HTML> <html> <head> <title>Big for loop</title> <script> function bigLoop() { for (var i = 0; i <= 10000; i += 1) { var j = i; } alert("Completed " + j + "iterations" ); } function sayHello(){ alert("Hello sir...." ); } </script> </head> <body> <input type = "button" onclick = "bigLoop();" value = "Big Loop" /> <input type = "button" onclick = "sayHello();" value = "Say Hello" /> </body> </html>
它將產生以下結果&負;
當您單擊大循環按鈕時,它在Firefox−中顯示以下結果;
What is Web Workers?
上面解釋的情況可以使用Web工作者來處理,他們將在不中斷用戶界面的情況下完成所有計算開銷較大的任務,並且通常在單獨的線程上運行。
Web Worker允許長時間運行的腳本,這些腳本不會被響應單擊或其他用戶交互的腳本中斷,並且允許長時間執行任務,而不會讓頁面保持響應。
webworker是後台腳本,它們相對較重,不打算大量使用。例如,爲400萬像素圖像的每個像素啓動一個worker是不合適的。
當腳本在Web工作者內部執行時,它無法訪問Web頁面的窗口對象(window.document),這意味著Web工作者不能直接訪問Web頁面和DOM API。儘管Web工作者無法阻止瀏覽器UI,但他們仍然可以消耗CPU周期,並使系統響應性降低。
How Web Workers Work?
Web工作程序是用JavaScript文件的URL初始化的,該文件包含工作程序將執行的代碼。此代碼設置事件偵聽器,並與從主頁生成它的腳本通信。下面是簡單的語法−
var worker = new Worker('bigLoop.js');
如果指定的javascript文件存在,瀏覽器將生成一個新的工作線程,該線程將異步下載。如果到工作進程的路徑返回404錯誤,則該工作進程將以靜默方式失敗。
如果應用程式有多個支持的JavaScript文件,則可以導入它們importScripts()方法,該方法以文件名作爲參數,用逗號分隔,如下所示−
importScripts("helper.js", "anotherHelper.js");
生成Web Worker後,Web Worker與其父頁面之間的通信將使用postMessage()方法完成。根據瀏覽器/版本的不同,postMessage()可以接受字符串或JSON對象作爲其單個參數。
使用主頁中的onmessage事件訪問Web Worker傳遞的消息。現在讓我們使用Web Worker編寫bigLoop示例。下面是主頁(hello.htm),它將生成一個web工作者來執行循環並返回變量j−的最終值;
<!DOCTYPE HTML> <html> <head> <title>Big for loop</title> <script> var worker = new Worker('bigLoop.js'); worker.onmessage = function (event) { alert("Completed " + event.data + "iterations" ); }; function sayHello() { alert("Hello sir...." ); } </script> </head> <body> <input type = "button" onclick = "sayHello();" value = "Say Hello"/> </body> </html>
下面是bigLoop.js文件的內容。這利用postMessage()API將通信傳遞迴主頁−
for (var i = 0; i <= 1000000000; i += 1) { var j = i; } postMessage(j);
這將產生以下結果&負;
Stopping Web Workers
Web工作者不會自行停止,但是啓動它們的頁面可以通過調用terminate()方法來停止它們。
worker.terminate();
已終止的Web工作進程將不再響應消息或執行任何其他計算。不能重新啓動工作進程;相反,可以使用相同的URL創建新的工作進程。
Handling Errors
下面顯示了將錯誤記錄到控制台的Web工作者JavaScript文件中的錯誤處理函數的示例。使用錯誤處理代碼,上面的示例將變爲以下−
<!DOCTYPE HTML> <html> <head> <title>Big for loop</title> <script> var worker = new Worker('bigLoop.js'); worker.onmessage = function (event) { alert("Completed " + event.data + "iterations" ); }; worker.onerror = function (event) { console.log(event.message, event); }; function sayHello() { alert("Hello sir...." ); } </script> </head> <body> <input type = "button" onclick = "sayHello();" value = "Say Hello"/> </body> </html>
Checking for Browser Support
以下是檢測瀏覽器中可用的Web輔助功能支持的語法−
<!DOCTYPE HTML> <html> <head> <title>Big for loop</title> <script src = "/js/modernizr-1.5.min.js"></script> <script> function myFunction() { if (Modernizr.webworkers) { alert("Congratulation!! you have web workers support." ); } else { alert("Sorry!! you do not have web workers support." ); } } </script> </head> <body> <button onclick = "myFunction()">Click me</button> </body> </html>
這將產生以下結果&負;