Heim > Artikel > Web-Frontend > 7 Dinge, die Sie über Web Worker wissen sollten
Mit Web Workern können Sie JavaScript-Code im Hintergrund ausführen, ohne die Webbenutzeroberfläche zu blockieren. Web Worker können die Gesamtleistung von Webseiten verbessern und auch das Benutzererlebnis verbessern. Web Worker gibt es in zwei Varianten: dedizierte Web Worker und gemeinsam genutzte Web Worker. In diesem Artikel werden sieben wichtige Aspekte von Web-Workern erläutert, die Sie kennen müssen, um sich für den Einsatz in Ihrer Anwendung zu entscheiden.
Normalerweise wird der JavaScript-Code, den Sie in eine Webseite schreiben, im selben Thread wie die Benutzeroberfläche ausgeführt. Aus diesem Grund friert die Benutzeroberfläche der Webseite ein, wenn Sie auf eine Schaltfläche klicken, die einen langwierigen Vorgang auslöst. Sie können die Benutzeroberfläche erst dann bearbeiten, wenn die Verarbeitung abgeschlossen ist. Mit Web-Workern können Sie JavaScript im Hintergrund ausführen, sodass die Benutzeroberfläche auch dann reagiert, wenn einige Skripts gleichzeitig ausgeführt werden. Der Hintergrundthread, der das Skript ausführt, wird oft als Arbeitsthread oder Worker bezeichnet. Sie können so viele Arbeiter hervorbringen, wie Sie möchten. Sie können Daten auch an ein Skript übergeben, das in einem Arbeitsthread ausgeführt wird, und den Wert nach Abschluss an den Hauptthread zurückgeben. Für Web Worker gelten jedoch folgende Einschränkungen:
Web Worker können von Webseiten aus nicht auf DOM-Elemente zugreifen.
Web Worker können über die Webseite nicht auf globale Variablen und JavaScript-Funktionen zugreifen.
Web Worker können die Funktionen „alert()“ oder „firmify()“ nicht aufrufen.
Auf Objekte wie Fenster, Dokument und übergeordnete Objekte kann in Web Workers nicht zugegriffen werden.
Sie können jedoch Funktionen wie setTimeout() und setInterval() verwenden. Sie können das XMLHttpRequest-Objekt auch verwenden, um Ajax-Anfragen an den Server zu stellen.
Es gibt zwei Arten von Web Workern: dedizierte Web Worker und gemeinsam genutzte Web Worker. Engagierte Web Worker leben und sterben mit den Webseiten, die sie erstellen. Dies bedeutet, dass auf dedizierte Web Worker, die innerhalb einer Webseite erstellt wurden, nicht über mehrere Webseiten hinweg zugegriffen werden kann. Shared Web Worker hingegen werden auf mehreren Webseiten gemeinsam genutzt. Die Worker-Klasse stellt dedizierte Web-Worker dar, während die SharedWorker-Klasse gemeinsam genutzte Web-Worker darstellt.
In vielen Fällen werden dedizierte Web Worker Ihren Bedarf decken. Dies liegt daran, dass Sie normalerweise bestimmte Skripts für eine Webseite in einem Arbeitsthread ausführen müssen. Manchmal müssen Sie jedoch ein Skript in einem Arbeitsthread ausführen, der mehreren Webseiten gemeinsam ist. In diesem Fall können Sie, anstatt viele dedizierte Web Worker zu erstellen, einen für jede Seite, genauso gut gemeinsam genutzte Web Worker verwenden. Ein gemeinsam genutzter Web-Worker, der von einer Webseite erstellt wurde, kann weiterhin von anderen Webseiten verwendet werden. Es kann nur zerstört werden, wenn alle Verbindungen zu ihm geschlossen sind. Shared Web Worker sind etwas komplizierter als dedizierte Web Worker.
Nachdem Sie nun die Grundlagen von Web Workern verstanden haben, sehen wir uns an, wie Sie dedizierte Web Worker verwenden. Bei den unten besprochenen Beispielen wird davon ausgegangen, dass Sie eine Webanwendung mit Ihren bevorzugten Entwicklungstools erstellt und außerdem die jQuery- und Modernizr-Bibliotheken in ihrem Skriptordner hinzugefügt haben. Fügen Sie die HTML-Seite zur Webanwendung hinzu und geben Sie den folgenden Code ein:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <script src="scripts/modernizr.js"></script> <script src="scripts/jquery-2.0.0.js"></script> <script type="text/javascript"> $(document).ready(function () { if (!Modernizr.webworkers) { alert("This browser doesn't support Web Workers!"); return; } $("#btnStart").click(function () { var worker = new Worker("scripts/lengthytask.js"); worker.addEventListener("message", function (evt) { alert(evt.data); },false); worker.postMessage(10000); }); }); </script> </head> <body> <form> <input type="button" id="btnStart" value="Start Processing" /> </form> </body> </html>
Die obige HTML-Seite enthält eine Schaltfläche (btnStart), die eine JavaScript-Verarbeitung auslöst. Bitte beachten Sie, dass diese Seite auf die Bibliotheken Modernizr und jQuery verweist. Der 3f1c4e4b6b16bbbd69b2ee476dc4f83a-Block enthält den ready()-Methodenhandler, und dieser Handler verarbeitet wiederum das Click-Ereignis von btnStart. Der ready()-Handler prüft zunächst, ob der Browser Web-Worker unterstützt. Dies erfolgt mithilfe der Webworkers-Eigenschaft von Modernizr. Wenn der Browser keine Web-Worker unterstützt, wird dem Benutzer eine Fehlermeldung angezeigt.
Anschließend stellt der Code eine Verbindung zum Click-Event-Handler von btnStart her. Der Code für den Click-Event-Handler ist wichtig, da er ein Worker-Objekt verwendet, um das Skript im Hintergrund auszuführen. Der Click-Event-Handler erstellt ein Worker-Objekt und speichert es in einer lokalen Variablen – Worker. Im Konstruktor wird der Pfad zur im Hintergrund auszuführenden JavaScript-Datei übergeben. Sie werden im Handumdrehen LongyTask.js erstellen. Der Code fügt dann einen Ereignishandler für das Nachrichtenereignis des Worker-Objekts hinzu. Das Nachrichtenereignis wird ausgelöst, wenn das Zielskript (in diesem Fall LengthyTask.js) einige Werte an die Webseite zurücksendet. Nachrichtenereignishandler können die Eigenschaft evt.data verwenden, um auf den zurückgegebenen Wert zuzugreifen. Schließlich wird die postMessage()-Methode für das Worker-Objekt aufgerufen, um die Ausführung von LengthyTask.js auszulösen. Mit der postMessage()-Methode können Sie auch Daten an das Zielskript übergeben. In diesem Beispiel wird eine Zahl (10000) an postMessage() übergeben, die angibt, wie viele Millisekunden die Verarbeitung dauern soll. Sie können im postMessage()-Aufruf beliebige andere Daten übergeben, beispielsweise JavaScript-Objekte oder Strings.
Die Datei „LengthyTask.js“ enthält den im Hintergrund auszuführenden Code, wie unten gezeigt:
addEventListener("message", function (evt) { var date = new Date(); var currentDate = null; do { currentDate = new Date(); } while (currentDate - date < evt.data); postMessage(currentDate); }, false);
上面的代码处理worker thread的消息事件。当主页面调用Worker对象上的postMessage()方法时,会引发消息事件。消息事件处理程序通过运行某些毫秒的do-while循环来模拟冗长的处理。此循环运行的毫秒数从主页传递(回忆前面讨论的postMessage())。因此,evt.data在此示例中返回10000。一旦长时间操作完成,代码调用postMessage()会把处理结果发送回主页面。在本例中,传递currentDate的值(currentDate是一个Date对象)。
如果你运行主网页并单击Start Processing按钮,那么你将在10秒后收到alert()。同时,页面的用户界面不会被阻止,你可以执行诸如滚动,点击等操作,表明来自LengthyTask.js的代码正在后台运行。
前面的示例使用了专用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(),以将处理结果发送到主页面。
有时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.responseText); }; xhr.send(); }, false);
上面显示的代码创建了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秒后,将显示一个包含此成功消息的警报对话框。
如果你的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)。
Manchmal möchten Sie möglicherweise die Ausführung einer Aufgabe in einem Worker abbrechen. Zu diesem Zweck können Sie den Worker zerstören, indem Sie seine Methode „terminate()“ aufrufen. Sobald ein Worker beendet wurde, können Sie ihn nicht wiederverwenden oder neu starten. Natürlich können Sie jederzeit eine weitere Worker-Instanz erstellen und verwenden. Denken Sie jedoch daran: „terminate()“ beendet den Worker sofort und gibt Ihnen keine Chance, Bereinigungsvorgänge durchzuführen.
Mit Web-Workern können Sie Skripte im Hintergrund ausführen, ohne dass die Web-Benutzeroberfläche einfriert. Es gibt zwei Arten: dedizierte Web-Worker und gemeinsam genutzte Web-Worker. Erstellen Sie für jede Webseite einen dedizierten Web-Worker und nutzen Sie einen gemeinsamen Web-Worker für die gemeinsame Nutzung auf mehreren Webseiten. Die Worker-Klasse repräsentiert einen dedizierten Web-Worker und die SharedWorker-Klasse repräsentiert einen gemeinsam genutzten Web-Worker. In diesem Artikel wird erläutert, wie beide Typen verwendet werden. Außerdem wird erläutert, wie mit Fehlern umgegangen wird und wie der Webworker XMLHttpRequest für die Kommunikation mit dem Webserver verwendet.
Das obige ist der detaillierte Inhalt von7 Dinge, die Sie über Web Worker wissen sollten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!