關於 Web Workers 你需要了解的 7 件事
介紹
Web Workers允許你在後台運行JavaScript代碼,而不會阻止web用戶界面。Web Workers可以提高網頁的整體性能,還可以增強用戶體驗。Web Workers有兩種風格 ——專用Web Workers和共享Web Workers。本文討論了你所需要知道的Web worker的七個關鍵方面,幫助你決定在應用程序中使用它們的話。
1.Web Workers允許你在後台運行JavaScript代碼
通常,你在Web頁面中編寫的JavaScript代碼在與用戶界面相同的線程中執行。這就是為什麼當你點擊一個會觸發漫長處理過程的按鈕,網頁的用戶界面會凍結。除非處理完成,否則你就無法工作於用戶界面。Web worker允許你在後台執行JavaScript,以便用戶界面保持響應,即使同時正在執行某些腳本。執行腳本的後台線程通常稱為worker thread或worker。你可以生成儘可能多的worker,只要你想。你還可以將數據傳遞到正在worker thread中執行的腳本,並在完成時將值返回到主線程。然而,Web Workers有一些限制,如下所示:
Web Workers無法從web頁面訪問DOM元素。
Web Workers無法從web頁面訪問全局變數和JavaScript函數。
Web Workers不能調用alert()或confirm()函數。
不能在Web Workers中訪問諸如窗口,文檔和parent這樣的對象。
但是,你可以使用setTimeout(),setInterval()等函數。你也可以使用XMLHttpRequest對象向伺服器發出Ajax請求。
2.Web Workers有兩種類型
Web Workers有兩種類型:專用Web Workers和共享Web Workers。專用Web Workers隨同創建它們的網頁一起存在和死亡。這意味著在網頁中創建的專用Web Workers無法通過多個網頁訪問。另一方面,共享Web Workers在多個網頁之間是共享的。Worker類代表專用Web Workers,而SharedWorker類代表共享Web Workers。
在許多情況下,專用Web Workers就可以滿足你的需求。這是因為通常你需要在worker thread中執行一個網頁的特定腳本。然而,有時,你需要在worker thread中執行一個腳本,並且這個worker thread對多個網頁通用。在這種情況下,創建許多專用Web Workers,每個頁面一個,還不如使用共享Web Workers。由一個網頁創建的共享web worker仍然可用於其他網頁。只有當所有到它的連接被關閉,才能毀壞它。共享Web Workers比專用Web Workers更複雜一點。
3.Worker對象代表專用Web Worker
現在,你了解了Web Workers的基礎知識,讓我們看看如何使用專用Web Workers。下面討論的示例假設你已使用喜歡的開發工具創建了一個Web應用程序,並且還在其Script文件夾中添加了jQuery和Modernizr庫。將HTML頁面添加到web應用程序,然後鍵入以下代碼:
上面的HTML頁面包含一個觸發一些JavaScript處理的按鈕(btnStart)。請注意,該網頁引用了Modernizr和jQuery庫。
前面的示例使用了專用Web worker。讓我們將同樣的示例轉換為使用共享Web worker。共享Web worker由SharedWorker對象表示。下面的代碼顯示了來自主頁的代碼的修改版本:
$(document).ready(function () {
if (!Modernizr.webworkers)
{
alert("This browser doesn"t support Web Workers!");
return;
}
$("#btnStart").click(function () {
var worker = new SharedWorker("scripts/sharedlengthytask.js"); worker.port.addEventListener("message", function (evt) { alert(evt.data); }, false); worker.port.start(); worker.port.postMessage(10000); });
});
注意用粗體字標記的代碼。它創建了一個SharedWorker實例,並在構造函數中傳遞SharedLengthyTask.js。你將很快創建此文件。然後,代碼將消息事件處理程序連接到SharedWorker對象的埠對象。消息處理程序函數執行與前面示例中相同的工作。然後代碼在埠對象上調用start()方法。最後,在埠對象上調用postMessage()方法將數據(10000)發送到共享worker thread。
SharedLengthyTask.js文件包含以下代碼:
var port;
addEventListener("connect", function (evt) {
port = evt.ports[0];
port.addEventListener("message", function (evt) {
var date = new Date();
var currentDate = null;
do {
currentDate = new Date();
} while (currentDate - date < evt.data);
port.postMessage(currentDate);
}, false);
port.start();
}, false);
代碼首先聲明一個名為port的變數,用於存儲埠對象的引用。這次處理了兩個事件——connect和message。當與共享Web worker建立連接時,會觸發connect事件。 connect事件處理程序捕獲evt.port [0]對象並將其存儲在之前聲明的埠變數中。然後在埠對象上連接消息事件處理程序。調用埠對象的start()方法來開始偵聽該埠上的消息。消息事件處理程序幾乎與你在前面的示例中編寫的消息事件處理程序相同,除了它附加到埠對象這一點。此外,在埠對象上調用postMessage(),以將處理結果發送到主頁面。
5. Web Workers可以使用XMLHttpRequest與伺服器通信
有時Web Worker可能需要與Web伺服器通信。例如,你可能需要駐留在某些RDBMS中的數據以便於客戶端處理。要完成此類任務,你可以使用XMLHttpRequest對象向伺服器端資源發出請求。實例化Worker對象和處理消息事件的整個過程保持不變。但是,你需要向伺服器端資源發出GET或POST請求。考慮下面的代碼:
addEventListener("message", function (evt) {
var xhr = new XMLHttpRequest(); xhr.open("GET", "lengthytaskhandler.ashx"); xhr.onload = function () { postMessage(xhr.r
上面顯示的代碼創建了XMLHttpRequest對象的實例。然後調用open()方法,並指定向伺服器端資源LengthyTaskHandler.ashx(一個ASP.NET通用處理程序)發出GET請求。(雖然此示例使用ASP.NET通用處理程序,但你可以使用任何其他伺服器端資源。)然後它處理XMLHttpRequest對象的load事件並調用postMessage()。 xhr.responseText作為postMessage()的參數。xhr.responseText將是ASP.NET通用處理程序作為響應返回的值。請求完成時引發load事件。
LengthyTaskHandler.ashx包含以下代碼:
namespace WebWorkersDemo
{
public class LengthyTaskHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context) { System.Threading.Thread.Sleep(10000); context.Response.ContentType = "text/plain"; context.Response.Write("Processing successful!"); }
public bool IsReusable
{
get
{
return false;
}
}
}
}
正如你可以看到,ProcessRequest()通過在Thread類上調用Sleep()方法來模擬一些冗長的處理,並阻止執行10秒。然後它返回一個成功消息「Processing successful!」給調用者。如果你在進行這些更改後運行主網頁,你會發現在10秒後,將顯示一個包含此成功消息的警報對話框。
6.你可以使用錯誤事件捕獲未處理的錯誤
如果你的Web worker正在進行一些複雜的操作,那麼你可能需要添加錯誤處理到主網頁代碼,以便在worker中出現任何未處理錯誤時,可以採取適當的操作。這可以通過處理Worker對象的錯誤事件來完成。每當work thread中存在任何未處理的錯誤時,就會拋出錯誤事件。以下代碼顯示了如何完成此操作:
$("#btnStart").click(function () {
var worker = new Worker("scripts/lengthytask.js");
worker.addEventListener("message", function (evt) {
alert(evt.data);
}, false);
worker.addEventListener("error", function (evt) { alert("Line #" + evt.lineno + " - " + evt.message + " in " + evt.filename); }, false); worker.postMessage(10000);
});
從上面的代碼可以看出,錯誤處理程序已經連接到worker對象的錯誤事件。錯誤處理函數接收一個事件對象,而該對象提供錯誤信息,例如發生錯誤的行號(evt.lineno),錯誤消息(evt.message)和發生錯誤的文件(evt.filename)。
7.你可以使用Terminate()方法終止worker
有時你可能會想要取消worker中正在執行的任務。對此,你可以通過調用其terminate()方法來摧毀Worker。一旦Worker終止,你就不能重新使用或重新啟動它。當然,你總是可以創建另一個Worker實例並使用它。但請記住,terminate()會立即殺死了worker,並且不會給你任何機執行清理操作。
總結
Web workers允許你在後台執行腳本而不凍結網頁用戶界面。有兩種類型——專用web worker和共享web worker。每個網頁創建專用web worker,而跨多個網頁使用共享web worker共享。Worker類代表專用web worker,SharedWorker類代表共享web worker。本文介紹了如何使用這兩種類型,文中還討論了如何處理錯誤以及webworker如何使用XMLHttpRequest與web伺服器通信。
原文:http://www.developer.com/lang/jscript/7-things-you-need-to-know-about-web-workers.html
譯文:http://www.codeceo.com/article/7-things-about-web-workers.html


※白話比特幣原理解密
※軟體架構設計中要注意的六個方面
※一篇文章學懂Shell腳本
※泛型的意義和作用是啥?
※前端必知的Emmet實用操作
TAG:全棧開發者中心 |
※關於Harden Vol.2 你需要知道這些
※穿Vetements tabi的人從不需要知道Martin Margiela是誰
※做一個好的設計,需要考慮那些因素byFoster+partners設計事務所
※《We Were Here Too》:這遊戲需要基情!
※iOS11越獄也許你需要它Workflow MiniSSH規則!
※需要Windows才能在發布時運行Oculus Rift
※拍攝MV竟然被捕!關於Teka$hi 6ix9ine 你需要了解的10個事實!
※Learning Dharma Requires Good Companions 學佛需要善友
※WPA2中的WiFi「Krack」漏洞:你需要知道的
※Forest: 節後收心,你需要這個專註助手 | Hello App
※急停變向?你可能需要一雙adidas Harden Vol.2
※Geoffrey Hinton:人工智慧需要重頭再來
※關於Oculus Rift 2虛擬現實設備我們需要知道的一切
※Supreme x LV | 機會來了,只需要19萬美刀,Supreme x Louis Vuitton法拉利直接開走!
※python開發利器,python shell和vim中都需要的tab補全方法
※Xbox老大Phil Spencer:微軟需要一個復甦的機會
※seo需要學習python嗎?學習python有什麼好處?
※Windows 10 Solitaire每年需要10美元才能移除廣告
※Bronzer VS Contour!節後胖五斤的你需要知道這些修容小技巧
※Kali Linux 是什麼,你需要它嗎?