Avant HTML5, JavaScript s'exécute dans les navigateurs travaillant de manière unique. Bien qu'il y ait eu de nombreuses façons d'implémenter des simulations multi-thread (telles que la méthode SetInterval, la méthode Settimeout, etc. En JavaScript), en substance, le programme exécute est toujours effectué par le moteur JavaScript d'une manière unique. Les threads de travailleur introduits dans HTML5 permettent au moteur JavaScript côté navigateur d'exécuter simultanément du code JavaScript, réalisant ainsi une bonne prise en charge pour la programmation multi-thread à côté du navigateur.
Multithreading en Javascript - Wewworker Les travailleurs Web de HTML5 peuvent être divisés en deux types de thread différents, l'un est le travailleur dédié au fil dédié et l'autre est le travailleur partagé de thread partagé. Les deux types de threads ont des utilisations différentes. Travailleur du web spécialUn travailleur dédié est connecté au script qui l'a créé. Il peut communiquer avec d'autres travailleurs ou composants du navigateur, mais il ne peut pas communiquer avec le DOM. La signification de dédiée est que ce fil ne traite qu'une seule exigence à la fois. Les threads dédiés sont implémentés dans divers navigateurs traditionnels sauf IE et peuvent être utilisés avec confiance.
Créer un filLa création d'un travailleur est simple, il suffit de passer le nom de fichier du fichier JavaScript qui doit être exécuté dans le thread au constructeur.
Communication du filLa communication entre le thread principal et le thread enfant utilise les méthodes de postmessage et d'ondum de l'objet de thread. Peu importe qui envoie des données auxquelles l'envoi et l'envoi utilisent la méthode de postmessage et le récepteur utilise la méthode OnMessage pour recevoir des données. PostMessage n'a qu'un seul paramètre, c'est-à-dire les données passées, et OnMessage n'a qu'un seul paramètre. Supposons que ce soit l'événement, les données reçues sont obtenues via event.data.
Envoyer des données JSONJSON est quelque chose nativement soutenu par JS. Il n'a pas besoin d'être utilisé pour rien. Utilisez simplement des données complexes dans JSON. Par exemple:
PostMessage ({'cmd': 'init', 'himestamp': date.now ()});
Gestion des erreursLorsqu'une erreur se produit dans un fil, son rappel d'événements OnError sera appelé. Par conséquent, la façon de gérer les erreurs est très simple, ce qui consiste à monter l'événement OnError de l'instance de fil. Cette fonction de rappel a une erreur de paramètre, qui a 3 champs: message - message d'erreur; Nom de fichier - fichier de script où l'erreur s'est produite; Lineno - Ligne où l'erreur s'est produite.
Détruire les filsÀ l'intérieur du fil, utilisez la méthode de fermeture pour se détruire. Dans le thread principal à l'extérieur du thread, la méthode de terminaison de l'instance de thread est utilisée pour détruire le thread.
Ce qui suit est un exemple pour voir le fonctionnement de base des threads:
Code html:
<! Doctype html>
<html>
<adal>
<meta http-equiv = "contenu-type" contenu = "text / html; charset = utf-8" />
<Title> Fibonacci du travailleur Web </TITME>
<script type = "text / javascript">
onload = function () {
var worker = nouveau travailleur ('fibonacci.js');
working.onMessage = fonction (événement) {
console.log ("Résultat:" + event.data);
};
working.onerror = fonction (erreur) {
console.log ("Error:" + error.Message);
};
Worker.PostMessage (40);
}
</cript>
</ head>
<body>
</docy>
</html>
Fichier de script fibonacci.js Code:
//fibonacci.js
var fibonacci = fonction (n) {
retour n <2? n: arguments.callee (n - 1) + arguments.Callee (n - 2);
};
onMessage = fonction (événement) {
var n = parseInt (event.data, 10);
postmessage (fibonacci (n));
};
Mettez-les dans le même répertoire, exécutez le fichier de page et affichez la console pour voir les résultats de l'exécution.
Il y a un autre point ici. Dans le fil principal, l'événement OnMessage peut être accroché d'une autre manière:
working.addeventListener ('message', fonction (événement) {
console.log ("Résultat:" + event.data);
}, FAUX);
Je pense personnellement que c'est très gênant, alors pourquoi ne pas utiliser directement OnMessage.
Utiliser d'autres fichiers de scriptLes travailleurs peuvent utiliser la méthode globale ImportScripts pour charger et utiliser d'autres fichiers de script dans le domaine ou des bibliothèques de classe. Par exemple, ce qui suit est des moyens légaux d'utiliser:
importations (); / * n'importe rien * /
importations ('foo.js'); / * importe juste "foo.js" * /
importationscripts ('foo.js', 'bar.js'); / * importe deux scripts * /
Après l'importation, vous pouvez utiliser directement les méthodes de ces fichiers. Voir un petit exemple en ligne:
/ **
* Utilisez la méthode d'importation pour introduire des scripts de ressources externes, nous utilisons ici la bibliothèque d'outils de calcul de formule mathématique Math_Utitilities.js
* Lorsque le moteur JavaScript charge ce fichier de ressources, continuez à exécuter le code suivant. Dans le même temps, le code suivant est accessible et appelé
* Variables et méthodes définies dans le fichier de ressources.
** /
ImportScripts ('math_utibles.js');
onMessage = fonction (événement)
{
var first = event.data.first;
var second = event.data.second;
calculer (premier, deuxième);
};
Fonction Calcule (premier, deuxième) {
// fait le travail de calcul
var commun_divisor = divisor (premier, deuxième);
var Common_Multiple = multiple (premier, deuxième);
postmessage ("travail fait!" +
"Le multiple le moins commun est" + Common_divisor +
"Et le plus grand diviseur commun est" + Common_Multiple);
}
Certains internautes sur Internet ont également pensé à utiliser la méthode d'importation ici pour résoudre le problème du préchargement des ressources (le navigateur précharge les ressources sans analyser et exécuter les ressources), et la raison est également très simple.
Nidification du filDans le fil du travailleur, vous pouvez également créer des threads enfants et diverses opérations sont les mêmes.
Problèmes de synchronisationLe travailleur n'a pas de mécanisme de verrouillage et les problèmes de synchronisation multithread ne peuvent être résolus que par le code (comme la définition des variables de signal).
Travailleur partagé Les travailleurs Web partagés conviennent principalement aux problèmes de la concurrence des connexions multiples. Parce qu'il doit faire face à plusieurs connexions, son API est légèrement différente des travailleurs dédiés. En plus de cela, les travailleurs Web partagés, comme les travailleurs dédiés, ne peuvent pas accéder au DOM et l'accès aux propriétés de formulaire est également restreint. Les travailleurs Web partagés ne peuvent pas non plus traverser les communications.Les scripts de page peuvent communiquer avec les travailleurs Web partagés, cependant, légèrement différent des travailleurs Web dédiés (en utilisant une communication de port implicite) est que la communication est explicitement effectuée en utilisant un objet de port et en attachant un gestionnaire d'événements de message.
Après avoir reçu le premier message du script de travailleur Web, le travailleur Web partagé joint un gestionnaire d'événements au port activé. Généralement, le gestionnaire exécutera sa propre méthode postMessage () pour renvoyer un message au code d'appel, puis la méthode start () du port génère un processus de message valide.
Regardez le seul exemple que vous pouvez trouver sur Internet: créez un fil partagé pour recevoir des instructions envoyées à partir de différentes connexions, puis implémentez sa propre logique de traitement des instructions. Une fois le traitement des instructions terminé, le résultat sera renvoyé à chaque utilisateur connecté différent.
Code html:
<! Doctype html>
<html>
<adal>
<meta charset = "utf-8">
<Title> Exemple de travailleur partagé: comment utiliser un travailleur partagé dans HTML5 </TITME>
<cript>
var worker = new SharedWorker ('SharedWorker.js');
var log = document.getElementById ('réponse_from_worker');
wearch.port.addeventListener ('message', fonction (e) {
// enregistrer les données de réponse dans la page Web
log.TextContent = e.data;
}, FAUX);
wearch.port.start ();
worker.port.postMessage («Ping From User Web Page ..»);
// La méthode suivante enverra les entrées de l'utilisateur à SharedWorker
Fonction PostMessageTosharedWorker (entrée)
{
// Définissez un objet JSON pour construire la demande
var instructions = {instruction: input.value};
wearch.port.postMessage (instructions);
}
</cript>
</ head>
<Body onload = ''>
<output id = 'réponse_from_worker'>
Exemple de travailleur partagé: comment utiliser un travailleur partagé dans HTML5
</utput>
Envoyez des instructions à un travailleur partagé:
<input type = "text" Autofocus onInput = "PostMessageToshAredWorker (this); return false;">
</ entrée>
</docy>
</html>
Code de fichier de script:
// Créez un thread partagé pour recevoir des instructions envoyées à partir de différentes connexions. Une fois le traitement des instructions terminé, le résultat sera renvoyé à chaque utilisateur connecté différent.
var connect_number = 0;
onConnect = fonction (e) {
connect_number = connect_number + 1;
// Obtenez le premier port ici
var port = e.ports [0];
Port.PostMessage («Une nouvelle connexion! Le numéro de connexion actuel est»
+ connect_number);
port.onMessage = fonction (e) {
// obtient des instructions du demandeur
Instruction var = e.data.instruction;
var Results = EXECUTE_INSTRUCTION (instruction);
Port.PostMessage ('Demande:' + Instruction + 'Response' + Résultats
+ 'du travailleur partagé ...');
};
};
/ *
* Cette fonction sera utilisée pour exécuter les instructions envoyées de demandeur
* Instruction @param
* @retour
* /
Fonction EXECUTE_INSTRUCTION (Instruction)
{
var result_value;
// Implémentez votre logique ici
// Exécuter l'instruction ...
return result_value;
}
Dans l'exemple de thread partagé ci-dessus, un objet de thread partagé est construit sur la page principale, c'est-à-dire chaque page de connexion utilisateur, et une méthode est définie pour envoyer les instructions utilisateur entrantes au thread partagé. Dans le même temps, Connect_number est défini dans l'extrait de code d'implémentation du thread partagé pour enregistrer le nombre total de connexion au thread partagé. Après cela, utilisez le processeur d'événements OnConnect pour accepter les connexions de différents utilisateurs et analyser les instructions qu'ils transmettent. Enfin, une méthode execute_instruction est définie pour exécuter les instructions de l'utilisateur. Une fois l'exécution des instructions terminée, le résultat sera renvoyé à chaque utilisateur.
Ici, nous n'avons pas utilisé le gestionnaire d'événements OnMessage du fil de travail comme l'exemple précédent, mais nous avons utilisé une autre méthode pour AddEventListener. En fait, comme mentionné précédemment, les principes de mise en œuvre de ces deux sont fondamentalement les mêmes, mais il existe de légères différences ici. Si vous utilisez AddEventListener pour accepter les messages à partir de threads partagés, vous devez d'abord utiliser la méthode wearch.port.start () pour démarrer ce port. Après cela, vous pouvez recevoir et envoyer des messages normalement comme la façon dont un fil de travail est utilisé.
Déclaration finale Des choses que vous pouvez faire dans un fil :1. Peut utiliser setTimeout (), ClearTimeout (), setInterval (), ClearInterval () et d'autres fonctions.
2. Peut utiliser des objets Navigator.
3. Peut utiliser xmlhttpRequest pour envoyer des demandes.
4. Vous pouvez utiliser le stockage Web dans le fil.
5. Vous pouvez utiliser Self pour obtenir la portée de ce fil dans le fil.
Des choses qui ne peuvent pas être faites dans les fils :1. Des objets DOM / BOM autres que Navigator ne peuvent pas être utilisés dans des threads, tels que la fenêtre et le document (si vous souhaitez fonctionner, vous ne pouvez envoyer des messages qu'au créateur de travailleurs et fonctionner via des fonctions de rappel).
2. Les variables et les fonctions dans le thread principal ne peuvent pas être utilisées dans le thread.
3. Les commandes de fonctionnement avec des effets de suspension ne peuvent pas être utilisées dans des threads, tels que l'alerte, etc.
4. JS ne peut pas être chargé sur les domaines dans les threads.
Les threads nécessitent également une consommation de ressources, et l'utilisation de threads apportera également une certaine complexité, donc s'il n'y a aucune raison suffisante d'utiliser des threads supplémentaires, ne les utilisez pas.
Référence pratiqueDocument officiel: http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html
Classification des travailleurs Web Description: http://www.w3schools.com/html5/html5_webworkers.asp
Modèle soucis: http://www.cuoxin.com/w3school/html5/
Présentation du travail Web: https://developer.mozilla.org/en/using_web_workers