Vor HTML5 arbeitete JavaScript in Browsern auf eine einzelne Weise. Obwohl es viele Möglichkeiten gab, Multi-Thread-Simulationen (wie die SetInterval-Methode, die SetTimeout-Methode usw. usw.) im Wesentlichen zu im Wesentlichen zu implementieren, wird das Programmauslauf immer noch von der JavaScript-Engine in einer einzigen Thread-Weise durchgeführt. Die in HTML5 eingeführten Worker-Threads ermöglichen es der Browser-Seite-JavaScript-Engine, JavaScript-Code gleichzeitig auszuführen, wodurch eine gute Unterstützung für die Browser-Side-Multi-Threade-Programmierung erreicht wird.
Multithreading in JavaScript - Webworker Webarbeiter in HTML5 können in zwei verschiedene Thread -Typen unterteilt werden, einer ist der dedizierte Thread -Dedicated Worker und der andere ist der freigegebene Thread Shared Worker. Die beiden Arten von Threads haben unterschiedliche Verwendungen. Spezielle WebarbeiterEin engagierter Arbeiter ist mit dem Skript verbunden, das es erstellt hat. Es kann mit anderen Arbeitern oder Browserkomponenten kommunizieren, kann jedoch nicht mit dem DOM kommunizieren. Die Bedeutung von engagiert ist, dass dieser Thread jeweils nur eine Anforderung verarbeitet. Dedizierte Themen werden in verschiedenen Mainstream -Browsern mit Ausnahme des IE implementiert und können mit Zuversicht verwendet werden.
Thread erstellenDas Erstellen eines Arbeiters ist einfach. Übergeben Sie einfach den Dateinamen der JavaScript -Datei, die im Thread an den Konstruktor ausgeführt werden muss.
FadenkommunikationDie Kommunikation zwischen dem Hauptfaden und dem untergeordneten Thread verwendet die Postmessage- und OnMessage -Methoden des Thread -Objekts. Unabhängig davon, wer Daten an wen sendet, verwendet das Senden und Senden die Postmessage -Methode, und der Empfänger verwendet die OnMessage -Methode, um Daten zu empfangen. Postmessage hat nur einen Parameter, dh die bestandenen Daten und OnMessage nur einen Parameter. Angenommen, es ist ein Ereignis, die empfangenen Daten werden über Event.Data erhalten.
Senden Sie JSON -DatenJSON ist etwas, das von JS nativ unterstützt wird. Es muss nicht für nichts verwendet werden. Verwenden Sie einfach komplexe Daten in JSON. Zum Beispiel:
postMessage ({'cmd': 'init', 'timestamp': date.now ()});
HandhabungsfehlerWenn in einem Thread ein Fehler auftritt, wird der Onerror -Ereignisrückruf aufgerufen. Daher ist der Weg, um mit Fehlern umzugehen, sehr einfach, das Onerror -Ereignis der Thread -Instanz zu montieren. Diese Rückruffunktion hat einen Parameterfehler, der 3 Felder hat: Meldung - Fehlermeldung; Dateiname - Skriptdatei, bei der der Fehler aufgetreten ist; LINENO - Zeile, in der der Fehler aufgetreten ist.
Zerstöre FädenVerwenden Sie im Faden die enge Methode, um sich selbst zu zerstören. Im Hauptfaden außerhalb des Fadens wird die Terminmethode der Thread -Instanz verwendet, um den Faden zu zerstören.
Das Folgende ist ein Beispiel, um den grundlegenden Betrieb von Threads anzuzeigen:
HTML -Code:
<! DocType html>
<html>
<kopf>
<meta http-äquiv = "content-type" content = "text /html; charset = utf-8" />
<title> Webarbeiter Fibonacci </title>
<script type = "text/javaScript">
onload = function () {
var Worker = neuer Arbeiter ('fibonacci.js');
Worker.onMessage = Funktion (Ereignis) {
console.log ("Ergebnis:" + event.data);
};
Worker.onError = Funktion (Fehler) {
console.log ("Fehler:" + error.message);
};
Worker.PostMessage (40);
}
</script>
</head>
<body>
</body>
</html>
Skriptdatei fibonacci.js Code:
//fibonacci.js
var fibonacci = function (n) {
N <2 zurückgeben? N: Argumente.Callee (n - 1) + Argumente.Callee (n - 2);
};
OnMessage = Funktion (Ereignis) {
var n = parseInt (Ereignis.Data, 10);
Postmessage (Fibonacci (n));
};
Legen Sie sie in das gleiche Verzeichnis, führen Sie die Datei aus und sehen Sie sich die Konsole an, um die Ergebnisse des Laufs anzuzeigen.
Hier gibt es noch einen Punkt. Im Hauptfaden kann das OnMessage -Ereignis auf andere Weise begeistert sein:
Worker.AdDeVentListener ('Nachricht', Funktion (Ereignis) {
console.log ("Ergebnis:" + event.data);
}, FALSCH);
Ich persönlich denke, es ist sehr problematisch. Warum also nicht OnMessage direkt verwenden?
Verwenden Sie andere SkriptdateienDie Arbeitnehmer können mit den globalen Methoden importscripts andere Domain-Skriptdateien oder Klassenbibliotheken verwenden und verwenden. Beispielsweise sind die folgenden gesetzlichen Möglichkeiten zu verwenden:
Importscripts ();/ * importiert nichts */
Importscripts ('foo.js'); / * importiert nur "foo.js" */
Importscripts ('foo.js', 'bar.js');/ * importiert zwei Skripte */
Nach dem Import können Sie die Methoden in diesen Dateien direkt verwenden. Siehe ein kleines Beispiel online:
/**
* Verwenden Sie die Methode importscripts, um externe Ressourcenskripte einzuführen.
* Wenn die JavaScript -Engine diese Ressourcendatei lädt, führen Sie den folgenden Code fort. Gleichzeitig kann der folgende Code zugegriffen und aufgerufen werden
* Variablen und Methoden in der Ressourcendatei definiert.
**//
Importscripts ('math_utilities.js');
OnMessage = Funktion (Ereignis)
{
var first = event.data.First;
var Second = event.data.second;
berechnen (zuerst, zweitens);
};
Funktion berechnen (zuerst, zweitens) {
// Die Berechnungsarbeit erledigen
var Common_divisor = Divisor (zuerst, zweitens);
var Common_multiple = multiple (zuerst, zweitens);
Postmessage ("Arbeit erledigt!" +
"Das am wenigsten häufige Mehrfaches ist" + Common_divisor +
"Und der größte gemeinsame Teiler ist"+Common_multiple);
}
Einige Internetnutzer im Internet dachten auch daran, die Methode importscripts hier zu verwenden, um das Problem der Ressourcenvorladung zu lösen (der Browser lädt die Ressourcen vor, ohne die Ressourcen zu analysieren und auszuführen), und der Grund ist auch sehr einfach.
FadennistungIm Arbeiter -Thread können Sie auch untergeordnete Threads erstellen, und verschiedene Operationen sind gleich.
SynchronisationsproblemeDer Arbeiter hat keinen Sperrmechanismus, und Multithread -Synchronisationsprobleme können nur durch Code gelöst werden (z. B. Signalvariablen).
Sharedwebworker Shared Web Workers eignen sich hauptsächlich für die Probleme mehrerer Verbindungen. Da es sich mit mehreren Verbindungen befassen muss, unterscheidet sich die API etwas von engagierten Arbeitnehmern. Darüber hinaus können freigegebene Webarbeiter wie dedizierte Arbeitnehmer nicht auf das DOM zugreifen, und der Zugriff auf Formulareigenschaften ist ebenfalls eingeschränkt. Auch gemeinsame Webarbeiter können die Kommunikation überschreiten.Seitenskripte können mit gemeinsam genutzten Webarbeitern kommunizieren. Etwas unterscheidet sich jedoch etwas von dedizierten Webarbeitern (unter Verwendung einer impliziten Portkommunikation), dass die Kommunikation explizit durch Verwendung eines Portobjekts und Anhängen eines Nachrichtenereignishandlers durchgeführt wird.
Nach Erhalt der ersten Nachricht aus dem Web Worker -Skript fügt der freigegebene Webarbeiter einen Ereignishandler an den aktivierten Port hinzu. Im Allgemeinen führt der Handler eine eigene PostMessage () -Methode aus, um eine Nachricht an den aufrufenden Code zurückzugeben, und dann generiert die Start () -Methode des Ports einen gültigen Nachrichtenprozess.
Sehen Sie sich das einzige Beispiel an, das Sie im Internet finden können: Erstellen Sie einen gemeinsam genutzten Thread, um Anweisungen aus verschiedenen Verbindungen zu erhalten, und implementieren Sie dann eine eigene Anweisungslogik. Nach Abschluss der Anweisungsbearbeitung wird das Ergebnis an jeden verschiedenen verbundenen Benutzer zurückgegeben.
HTML -Code:
<! DocType html>
<html>
<kopf>
<meta charset = "utf-8">
<title> Beispiel für Shared Worker: Wie man freigegebener Mitarbeiter in HTML5 </title> verwendet
<Script>
var Worker = neuer Sharedworker ('Sharedworker.js');
var log = document.getElementById ('response_from_worker');
Worker.port.AddeventListener ('Nachricht', Funktion (e) {
// Die Antwortdaten auf der Webseite protokollieren
log.textContent = e.data;
}, FALSCH);
Worker.port.start ();
Worker.port.PostMessage ('Ping von Benutzerwebseite ..');
// Die folgende Methode sendet die Benutzereingabe an den Shared Worker
Funktion postmessagetosharedworker (Eingabe)
{
// Definieren Sie ein JSON -Objekt, um die Anforderung zu konstruieren
var Anweisungen = {Anweisung: input.Value};
Worker.port.PostMessage (Anweisungen);
}
</script>
</head>
<Body Onload = ''>
<output id = 'response_from_worker'>
Beispiel für gemeinsames Arbeiter: So verwenden Sie Shared Worker in HTML5
</output>
Senden Sie Anweisungen an den gemeinsamen Arbeitnehmer:
<Eingabe type = "text" Autofocus onInput = "postMessAgetosharedworker (this); return false;">
</input>
</body>
</html>
Skriptdateicode:
// Erstellen Sie einen gemeinsam genutzten Thread, um Anweisungen zu erhalten, die von verschiedenen Verbindungen gesendet werden. Nach Abschluss der Anweisungsbearbeitung wird das Ergebnis an jeden verschiedenen verbundenen Benutzer zurückgegeben.
var Connect_Number = 0;
onconnect = function (e) {
connect_number = connect_number+ 1;
// Holen Sie sich hier den ersten Port
var port = e.ports [0];
Port.PostMessage ('Eine neue Verbindung! Die aktuelle Verbindungsnummer ist'
+ connect_number);
port.onmessage = function (e) {
// Anweisungen vom Antragsteller erhalten
var Anweisung = e.data.Instruction;
var resends = execute_instruction (Anweisung);
post.postmessage ('Anfrage:'+Anweisung+'Antwort'+Ergebnisse
+'von Shared Worker ...');
};
};
/*
* Diese Funktion wird verwendet, um die Anweisungen vom Antragsteller auszuführen
* @param Anweisung
* @zurückkehren
*/
Funktion execute_instruction (Anweisung)
{
var result_value;
// Implementieren Sie Ihre Logik hier
// die Anweisung ausführen ...
return result_value;
}
Im obigen gemeinsam genutzten Thread -Beispiel wird auf der Hauptseite ein freigegebenes Thread -Objekt konstruiert, dh jede Benutzerverbindungsseite, und eine Methode wird definiert, um die eingehenden Benutzeranweisungen an den freigegebenen Thread zu senden. Gleichzeitig ist Connect_Number im Implementierungscode -Snippet des freigegebenen Threads definiert, um die Gesamtzahl der an den gemeinsam genutzten Thread angeschlossenen Aufzeichnungen aufzuzeichnen. Verwenden Sie danach den Onconnect -Ereignisprozessor, um Verbindungen von verschiedenen Benutzern zu akzeptieren und die Anweisungen zu analysieren, die sie ergeben. Schließlich wird eine Methode execute_instruction definiert, um die Anweisungen des Benutzers auszuführen. Nach Abschluss der Anweisungsausführung wird das Ergebnis an jeden Benutzer zurückgegeben.
Hier haben wir den OnMessage -Event -Handler des Worker -Threads nicht wie im vorherigen Beispiel verwendet, sondern eine andere Methode, um AddEventListener zu erhalten. Wie bereits erwähnt, sind die Implementierungsprinzipien dieser beiden im Grunde genommen gleich, aber hier gibt es einige geringfügige Unterschiede. Wenn Sie AddEventListener verwenden, um Nachrichten aus freigegebenen Threads zu akzeptieren, müssen Sie zunächst die Methode von Worker.port.start () verwenden, um diesen Port zu starten. Danach können Sie Nachrichten empfangen und senden, genau wie die Art und Weise, wie ein Worker -Thread verwendet wird.
Endgültige Aussage Dinge, die Sie in einem Thread tun können :1. kann setTimeout (), clearimeout (), setInterval (), clearInterval () und andere Funktionen verwenden.
2. kann Navigator -Objekte verwenden.
3. kann XMLHTTPrequest verwenden, um Anfragen zu senden.
4.. Sie können Webspeicher im Thread verwenden.
5. Sie können sich selbst verwenden, um den Umfang dieses Threads in den Thread zu erhalten.
Dinge, die in Threads nicht getan werden können :1. DOM/BOM -Objekte als Navigator können nicht in Threads wie Fenster und Dokument verwendet werden (wenn Sie bedienen möchten, können Sie nur Nachrichten an den Arbeiter -Ersteller senden und durch Rückruffunktionen arbeiten).
2. Variablen und Funktionen im Hauptdhreop können im Thread nicht verwendet werden.
3. Die Betriebsbefehle mit Suspend -Effekten können nicht in Threads wie Alarm usw. verwendet werden.
4. JS kann nicht über Domänen in Threads geladen werden.
Threads erfordern auch den Ressourcenverbrauch, und die Verwendung von Threads bringt auch eine gewisse Komplexität. Wenn es also keinen ausreichenden Grund gibt, zusätzliche Threads zu verwenden, verwenden Sie sie nicht.
Praktische ReferenzOffizielles Dokument: http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html
Webworker -Klassifizierung Beschreibung: http://www.w3schools.com/html5/html5_webworkers.asp
Vorlage Sorgen: http://www.cuoxin.com/w3school/html5/
Webworker -Übersicht: https://developer.mozilla.org/en/using_web_workers