Web Worker est une solution multithread javascript fournie par HTML5. Nous pouvons confier du code gourmand en calcul au Web Worker pour qu'il s'exécute sans geler l'interface utilisateur.
1 : Comment utiliser WorkerLe principe de base de Web Worker est d'utiliser la classe Worker pour charger un fichier JavaScript dans le thread principal actuel de JavaScript afin d'ouvrir un nouveau thread, ce qui a pour effet d'exécuter sans blocage et fournit une interface d'échange de données entre le thread principal. et le nouveau fil de discussion : postMessage, onmessage.
Alors comment l’utiliser, regardons un exemple :
//worker.jsonmessage =function (evt){ var d = evt.data;//Obtenir les données envoyées via evt.data postMessage(d);//Envoyer les données obtenues au thread principal}Page HTML : test.html
<!DOCTYPE HTML><html><head> <meta http-equiv=Content-Type content=text/html; charset=utf-8/> <script type=text/javascript>//thème principal de la page WEB var worker = new Worker(worker.js); //Créez un objet Worker et transmettez-lui l'URL du script qui sera exécuté dans le nouveau thread worker.postMessage(hello world); =function(evt){ //Recevoir la fonction de données console.log(evt.data) du travailleur ; //Émettre les données envoyées par le travailleur} </script> </head> <body></body>< /html>Après avoir ouvert test.html avec le navigateur Chrome, la console affiche hello world, indiquant que le programme est exécuté avec succès.
À partir de cet exemple, nous pouvons voir que l’utilisation des Web Workers est principalement divisée en les parties suivantes :
Fil principal WEB :
1. Chargez un fichier JS via worker = new Worker( url ) pour créer un travailleur et renvoyer une instance de travailleur.
2. Envoyez des données au travailleur via la méthode worker.postMessage(data).
3. Liez la méthode worker.onmessage pour recevoir les données envoyées par le travailleur.
4. Vous pouvez utiliser worker.terminate() pour mettre fin à l'exécution d'un travailleur.
nouveau fil de travail :
1. Envoyez les données au thread principal via la méthode postMessage(data).
2. Liez la méthode onmessage pour recevoir les données envoyées par le thread principal.
2 : Que peut faire le travailleur ?Maintenant que nous savons comment utiliser Web Worker, à quoi sert-il et quels problèmes peut-il nous aider à résoudre. Regardons un exemple de la séquence de Fibonacci.
Comme nous le savons tous, en mathématiques, la séquence de Fibonacci est définie de manière récursive : F0=0, F1=1, Fn=F(n-1)+F(n-2) (n>=2, n∈N*), L'implémentation courante de javascript est :
var fibonacci =function(n) { return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);};//fibonacci(36)Le temps d'exécution de cette méthode pour calculer la séquence de Fibonacci de 39 dans Chrome est de 19 097 millisecondes, mais lorsqu'il s'agit de calculer 40, le navigateur indique directement que le script est occupé.
Étant donné que JavaScript est exécuté dans un seul thread, le navigateur ne peut pas exécuter d'autres scripts JavaScript pendant le processus de calcul de la séquence, et le thread de rendu de l'interface utilisateur sera également suspendu, provoquant l'entrée du navigateur dans un état zombie. Utiliser un web worker pour placer le processus de calcul de la séquence dans un nouveau thread évitera cette situation. Voir des exemples spécifiques :
//fibonacci.jsvar fibonacci =function(n) { return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);};onmessage =function(event) { var n = parseInt (event.data, 10); postMessage(fibonacci(n));};Page HTML : fibonacci.html
<!DOCTYPE HTML><html><head><meta http-equiv=Content-Type content=text/html; charset=utf-8/><title>travailleur web fibonacci</title><script type=text/javascript > onload =function(){ var worker =new Worker('fibonacci.js'); worker.addEventListener('message', function(event) { var timer2 = (nouveau Date().valueOf(); console.log( 'Result:'+event.data, 'Time:'+ timer2, 'Temps pris:'+ ( timer2 - timer ) }, false); ( new Date()).valueOf(); console.log('Démarrer le calcul : 40', 'Time:' + timer ); console.log('La fonction timer a été exécutée lors du calcul de la séquence', 'Time:'+ (new Date()).valueOf() },1000 worker.postMessage(40); J'ai exécuté ', 'time:'+ (new Date()).valueOf() ); } </script></head><body></body></html> lors du calcul de la séquenceOuvrez fibonacci.html dans Chrome et la console obtient le résultat suivant :
Commencez à compter : 40 Heure : 1316508212705
Quand j'ai calculé la séquence, j'ai exécuté l'heure : 1316508212734
La fonction timer exécutée lors du calcul de la séquence : 1316508213735
Résultat : 102334155 Heure : 1316508262820 Temps écoulé : 50115
Cet exemple montre que le calcul de la séquence de Fibonacci effectué dans le travailleur n'affecte pas l'exécution du code du thread principal. Il est entièrement calculé dans son propre thread indépendant et les résultats ne sont renvoyés au thread principal qu'une fois le calcul terminé. complété.
À l'aide de Web Workers, nous pouvons effectuer certaines opérations complexes et à grande échelle sur le front-end sans affecter l'affichage de la page, et l'invite dégoûtante de script occupé ne s'affichera pas.
L'exemple suivant utilise un travailleur Web pour calculer les pixels de la scène. Lorsque la scène est ouverte, elle est dessinée un par un. Un travailleur ne calcule qu'une seule valeur de pixel.
Trois : Autres tentatives du travailleurNous savons déjà que Worker crée un travailleur en recevant une URL, pouvons-nous donc utiliser des Web Workers pour effectuer des requêtes similaires à jsonp ? Comme nous le savons tous, jsonp charge les données json en insérant des balises de script, et l'élément de script charge et exécute The. le processus est entièrement bloquant. Ce serait formidable si les Web Workers pouvaient être utilisés pour implémenter le chargement asynchrone.
L'exemple suivant chargera des données JSON de 169,42 Ko via trois méthodes différentes : web worker, jsonp et ajax.
// /aj/webWorker/core.jsfunction $E(id) { return document.getElementById(id);}onload =function() { //Charger via le web worker $E('workerLoad').onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face2'; var d = (nouvelle Date()).valueOf(); Worker(url); worker.onmessage =function(obj) { console.log('web worker: '+ ((new Date()).valueOf() - d)); E('jsonpLoad').onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face1'; var d = (nouveau Date()).valueOf(); STK.core.io.scriptLoader({ méthode:'post', url : url, onComplete : function() { console.log('jsonp: '+ ((nouvelle Date()) .valueOf() - d)); } }); //Charger $E('ajaxLoad') via ajax.onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face'; var d = (new Date()).valueOf(); STK.core.io.ajax({ url : url, onComplete : function( json) { console.log('ajax: '+ ((new Date()).valueOf() - d));Page HTML :/aj/webWorker/worker.html
<!DOCTYPE HTML><html><head><meta http-equiv=Content-Type content=text/html; charset=utf-8/><title>Exemple de travailleur : charger des données</title><script src=http ://js.t.sinajs.cn/STK/js/gaea.1.14.js type=text/javascript></script><script type=text/javascript src=http://js.wcdn.cn/aj/webWorker/core.js></script></head><body> <input type=button id=workerLoad value=web worker load></input> < type d'entrée=id du bouton=valeur jsonpLoad=chargement jsonp></input> <type d'entrée=id du bouton=valeur ajaxLoad=chargement ajax></input></body></html>
Configurer HÔTE
127.0.0.1 js.wcdn.cn
Accédez à la page via http://js.wcdn.cn/aj/webWorker/worker.html, puis chargez les données de trois manières pour obtenir la sortie de la console :
travailleur Web : 174jsonp : 25ajax : 38
Après avoir essayé plusieurs fois, j'ai constaté que le décalage horaire entre le chargement des données via jsonp et ajax n'est pas très différent et que le temps de chargement du Web Worker est toujours à un niveau élevé, donc utiliser Web Worker pour charger des données est encore relativement lent, même dans le cas d'un volume de données important, il n'y a aucun avantage, il se peut que Worker prenne du temps pour initialiser de nouveaux threads. Il n’y a aucun avantage autre que d’être non bloquant lors du chargement.
Alors, le travailleur Web peut-il prendre en charge le chargement de js entre domaines ? Cette fois, nous accédons à la page via http://127.0.0.1/aj/webWorker/worker.html Lorsque nous cliquons sur le bouton de chargement du travailleur Web, rien n'est reflété dans Chrome FF6. Le message d'erreur suivant apparaît. De cela, nous pouvons savoir que Web Worker ne prend pas en charge le chargement inter-domaines de JS, ce qui est une mauvaise nouvelle pour les sites Web qui déploient des fichiers statiques sur un serveur statique distinct.
Par conséquent, les Web Workers ne peuvent être utilisés que pour charger des données JSON dans le même domaine, et ajax peut déjà le faire, et il est plus efficace et plus polyvalent. Laissez le travailleur faire ce pour quoi il est bon.
Quatre : RésuméLes travailleurs du Web ont fière allure, mais ils sont diaboliques.
Ce que nous pouvons faire :
1. Vous pouvez charger un JS pour effectuer un grand nombre de calculs complexes sans suspendre le processus principal et communiquer via postMessage, onmessage
2. Vous pouvez charger des fichiers de script supplémentaires dans le travailleur via importScripts(url)
3. Vous pouvez utiliser setTimeout(), clearTimeout(), setInterval() et clearInterval()
4. Vous pouvez utiliser XMLHttpRequest pour envoyer des requêtes
5. Peut accéder à certaines propriétés du navigateur
Quelles sont les limites :
1.Impossible de charger JS sur plusieurs domaines
2. Le code du travailleur ne peut pas accéder au DOM
3. Différents navigateurs ont différentes implémentations de Worker. Par exemple, FF permet la création de nouveaux Workers dans Workers, mais pas Chrome.
4. Tous les navigateurs ne prennent pas en charge cette nouvelle fonctionnalité
Ce qui précède représente l’intégralité du contenu de cet article. J’espère qu’il sera utile à l’étude de chacun. J’espère également que tout le monde soutiendra le réseau VeVb Wulin.