Wenn es um HTML5 geht, reden die Leute immer darüber. Es gibt so viele Funktionen und interessante APIs, die erfrischend sind. Allerdings bleiben viele Kinderschuhe immer noch auf der semantischen Ebene und ignorieren die Leistungsfähigkeit von HTML5.
In diesem Abschnitt besprechen wir Multithread-Web-Worker.
1. Machen Sie deutlich, dass JavaScript Single-Threaded istEin Hauptmerkmal der JavaScript-Sprache ist, dass sie Single-Threaded ist, was bedeutet, dass sie jeweils nur eine Sache ausführen kann.
Es klingt seltsam, warum nicht mit Multithreading entwerfen, um die Effizienz zu verbessern? Wir können ein Szenario annehmen:
Angenommen, JavaScript
verfügt über zwei Threads gleichzeitig. Ein Thread fügt einem bestimmten DOM
Knoten Inhalte hinzu und der andere Thread löscht den Knoten. Welchen Thread sollte der Browser in diesem Fall verwenden?
Als Browser-Skriptsprache besteht der Hauptzweck von JavaScript
darin, mit Benutzern zu interagieren und DOM
zu manipulieren.
Dies legt fest, dass es nur Single-Threaded sein kann, da es sonst zu sehr komplexen Synchronisationsproblemen kommt. Um Komplexität zu vermeiden, wurde JavaScript
von Anfang an auf Single-Threading umgestellt. Dies ist zu einem Kernmerkmal der Sprache geworden und dürfte kurzfristig nur schwer zu ändern sein.
Single-Threading war schon immer ein Problempunkt. Um die Rechenleistung von Multi-Core CPU
zu nutzen, schlägt HTML5
den Web Worker
Standard vor, der es JavaScript
Skripten ermöglicht, mehrere Threads zu erstellen. Der untergeordnete Thread wird jedoch vollständig vom Hauptthread gesteuert und darf DOM
nicht bedienen.
Daher ändert dieser neue Standard nichts an der Single-Threaded-Natur von JavaScript
.
Web Workers
ist eine JavaScript
-Multithreading-Lösung, die von modernen Browsern bereitgestellt wird. Wir können viele Verwendungsszenarien finden:
1. Wir können Web Worker
verwenden, um einige rechenintensive Operationen durchzuführen.
2. Polling kann implementiert und bestimmte Zustände geändert werden;
3. Aktualisierung des Header-Nachrichtenstatus, z. B. Benachrichtigung über die Anzahl der Nachrichten im Seitenheader;
4. Hochfrequente Benutzerinteraktion, zum Beispiel Rechtschreibprüfung: Unterstützung von Benutzern bei der Durchführung von Eingabefehlerkorrektur- und Korrekturfunktionen basierend auf Benutzereingabegewohnheiten, historischen Aufzeichnungen, Cache und anderen Informationen
5. Verschlüsselung: Die Verschlüsselung kann manchmal sehr zeitaufwändig sein, insbesondere wenn Sie häufig viele Daten verschlüsseln müssen (z. B. Daten vor dem Senden an den Server verschlüsseln).
6. Daten vorab abrufen: Um Ihre Website oder Webanwendung zu optimieren und die Ladezeit der Daten zu verbessern, können Sie Workers
verwenden
um einige Daten im Voraus zu laden, falls Sie sie benötigen.
Verschlüsselung ist ein großartiges Szenario für die Verwendung Web Worker
da sie keinen Zugriff auf DOM
oder andere Zauberei erfordert, sondern lediglich Algorithmen zur Durchführung von Berechnungen verwendet. Da die Öffentlichkeit sensiblen personenbezogenen Daten zunehmend Aufmerksamkeit schenkt, sind Informationssicherheit und Verschlüsselung zu obersten Prioritäten geworden. Dies lässt sich am jüngsten Vorfall 12306 mit Benutzerdatenlecks widerspiegeln.
Sobald die Berechnung im Worker durchgeführt wird, erfolgt sie nahtlos für den Benutzer und hat keinen Einfluss auf die Benutzererfahrung.
3. Kompatibilität 4. Grundkonzepte1. Denken Sie zunächst daran, zu beurteilen, ob es unterstützt wird
if (window.Worker) { ...}
2. Das Erstellen eines neuen worker
ist einfach
const myWorker = new Worker('worker.js');
Die postMessage()-Methode und der onmessage-Ereignishandler sind die schwarze Magie von Workers.
3. postMessage
wird zum Senden von Nachrichten und onmessage
zum Abhören von Nachrichten verwendet.
const worker = new Worker('src/worker.js');worker.onmessage = e => { console.log(e.data);};worker.postMessage('How are you!');
Bei Verwendung im Hauptthread müssen onmessage
und postMessage()
am worker
-Objekt hängen, bei Verwendung im worker
ist dies jedoch nicht erforderlich. Der Grund dafür ist, dass worker
worker
praktisch den globalen Geltungsbereich darstellt.
4. Ausnahmebehandlung:
worker.onerror = function(error) { console.log(error.message); throw error;};
5. Beenden Sie worker
worker.terminate();
Der worker
wird sofort beendet, ohne dass er die Möglichkeit hat, seine Vorgänge abzuschließen oder aufzuräumen.
6. Im worker
Thread können workers
zum Schließen auch ihre eigene close
-Methode aufrufen:
schließen();5. Schnellstart
Um es schnell zu verstehen, machen wir ein kleines Beispiel: Die Projektstruktur ist wie folgt
├── index.html└── src ├── main.js └── worker.js
HTML
<html><head> <title>Web Work Demo</title> <meta charset=UTF-8 /></head><body> <div id=app> Hallo Jartto </div> <script src=src /main.js></script></body></html>
main.js
const worker = new Worker('src/worker.js');worker.onmessage = e => { const message = e.data; console.log(`[From Worker]: ${message}`); ('app').innerHTML = message;};worker.postMessage('Gut geschrieben!');
Work.js
onmessage = e => { const message = e.data; console.log(`[From Main]: ${message}`); if(message.indexOf('Good') > -1) { postMessage('Danke für Ihre Unterstützung '); }};
Der Code ist sehr einfach. Der Hauptthread sendet: „Es ist so gut geschrieben!“
Der Web-Mitarbeiter empfing die Nachricht und stellte fest, dass der Inhalt das Wort „gut“ enthielt, und schickte ihn an den Hauptthread zurück: „Vielen Dank für Ihre Unterstützung.“
6. Einschränkungen 1. Innerhalb worker
können DOM
-Knoten nicht direkt manipuliert werden und die Standardmethoden und -eigenschaften des window
können nicht verwendet werden. Wir können jedoch eine große Anzahl von Dingen unter dem window
verwenden, einschließlich Datenspeichermechanismen wie WebSockets
, IndexedDB
und FireFox OS
spezifischen Data Store API
.
Hier ist ein Beispiel, wir ändern main.js
:
const worker = new Worker('src/worker.js');worker.onmessage = e => { const message = e.data; console.log(`[From Worker]: ${message}`); ('app').innerHTML = message;};+ worker.onerror = function(error) {+ console.log(error);+ worker.terminate();+ };worker.postMessage('Gut geschrieben!');
Lassen Sie uns work.js
erneut ändern
+ warning('jartto');onmessage = e => { const message = e.data; console.log(`[From Main]: ${message}`); if(message.indexOf('good') > - 1) { postMessage('Vielen Dank für Ihre Unterstützung' }};
Zu diesem Zeitpunkt wird beim Ausführen Folgendes gemeldet:
Dies liegt daran: Der Kontext, in dem worker.js
ausgeführt wird, unterscheidet sich vom Kontext, in dem HTML
der Hauptseite ausgeführt wird. Das Objekt der obersten Ebene ist nicht Window
, der globale Kontext für die Ausführung woker.js
, sondern WorkerGlobalScope
. Lassen Sie es uns im Detail erklären.
2. Die Datenübertragung zwischen workers
und dem Hauptthread erfolgt über einen solchen Nachrichtenmechanismus: Beide Parteien verwenden die Methode postMessage()
, um ihre eigenen Nachrichten zu senden, und verwenden den Ereignishandler onmessage
, um auf die Nachricht zu antworten (die Nachricht ist in enthalten). das data
des Message
).
Dabei werden Daten nicht weitergegeben, sondern kopiert.
3. Gleiche Ursprungsbeschränkung
Die Worker
-Thread zugewiesene Skriptdatei muss denselben Ursprung haben wie die Skriptdatei des Hauptthreads.
4. Dateibeschränkungen
Der Worker
-Thread kann keine lokalen Dateien lesen, d. h. er kann das lokale Dateisystem (file://)
nicht öffnen. Das von ihm geladene Skript muss vom Server stammen.
5. Lokale Dateien nicht erlaubt
Nicht erfasster SecurityError: Es konnte kein Worker erstellt werden:
Skript unter '(path)/worker.js'
Vom Ursprung „null“ aus kann nicht darauf zugegriffen werden.
Chrome lässt Sie keine Web-Worker laden, wenn Sie Skripts aus einer lokalen Datei ausführen.
Wie kann man es also lösen? Wir können einen lokalen Server starten. Es wird empfohlen http-server
zu verwenden, der einfach und benutzerfreundlich ist.
6. Inhaltssicherheitsrichtlinie
worker
verfügt über einen eigenen Ausführungskontext, der sich von dem document
unterscheidet, das ihn erstellt hat. Im Allgemeinen ist worker
also nicht durch die Inhaltssicherheitsrichtlinie document
(oder des übergeordneten worker
) eingeschränkt, das ihn erstellt hat.
Nehmen wir ein Beispiel: Angenommen, ein document
hat die folgende Header-Deklaration:
Inhaltssicherheitsrichtlinie: script-src 'self'
Ein Teil des Zwecks dieser Deklaration besteht darin, zu verhindern, dass der darin enthaltene Skriptcode die Methode eval()
verwendet. Wenn der Skriptcode jedoch einen worker
erstellt, kann Code, der im Kontext worker
ausgeführt wird, eval()
verwenden.
Um einen CSP für einen Worker anzugeben, muss der Anfrage zum Senden des Worker-Codes selbst ein CSP angehängt werden.
Die einzige Ausnahme besteht darin, dass worker
document
oder worker
CSP
erbt, der es erstellt hat, wenn die Quelle des worker
-Skripts ein global eindeutiger Bezeichner ist (z. B. gibt seine URL
ein Datenschema oder blob
an).
Darüber finden wir die Dokumentation zu MDN
:
1. self
:
Wir können die self
Eigenschaft von WorkerGlobalScope
verwenden, um einen Verweis auf das Objekt selbst zu erhalten.
2. location
:
Das location
gibt WorkerLocation
Objekt zurück, das dem Thread bei seiner Erstellung zugeordnet war. Es stellt die absolute URL
der Skriptressource dar, die zum Initialisieren des Arbeitsthreads verwendet wurde. Dieser URL
Ressourcenspeicherort ändert sich nicht, auch wenn die Seite mehrmals umgeleitet wird.
3. close
:
Schließen Sie den aktuellen Thread, ähnlich wie bei terminate
.
4. caches
:
Der aktuelle Kontext verfügt über CacheStorage
um die Offline-Verfügbarkeit sicherzustellen und die Antwort auf die Anfrage kann angepasst werden.
5. console
:
Unterstützt console
.
6. importScripts
Mit importScripts()
können wir Bibliotheksfunktionen über url
in worker
laden.
7. XMLHttpRequest
Damit können Ajax
Anfragen gestellt werden.
8. Sie können Folgendes verwenden:
Es gibt viele API
, die verwendet werden können, daher werde ich hier nicht einzeln Beispiele nennen.
Wenn worker
auf einen laufenden Fehler stößt, wird sein onerror
Ereignishandler aufgerufen. Es wird ein Ereignis namens error
empfangen, das die ErrorEvent
Schnittstelle erweitert. Die Veranstaltung sprudelt nicht und kann abgesagt werden.
Um zu verhindern, dass die Standardaktion ausgelöst wird, kann der Worker die Methode „preventDefault()“ des Fehlerereignisses aufrufen.
Wir verwenden üblicherweise die folgenden drei Schlüsselinformationen für Fehlerereignisse:
worker.onerror = function(error) { console.log(error.message); throw error;};
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Ich hoffe auch, dass jeder das VeVb Wulin Network unterstützt.