Maison  >  Article  >  interface Web  >  Solution JavaScript multithread HTML5 Web Worker - introduction détaillée du code du Worker dédié et du Worker partagé

Solution JavaScript multithread HTML5 Web Worker - introduction détaillée du code du Worker dédié et du Worker partagé

黄舟
黄舟original
2017-03-11 16:18:182175parcourir

Il faut dire que HTML5 fournit de nombreuses fonctionnalités puissantes
Il bouleverse même notre compréhension précédente du JavaScript monothread
Il fournit une solution multithread pour JavaScript
Cette nouvelle fonctionnalité s'appelle Web Worker
(Il n'y avait pas de multi-thread avant, setTimeout et ainsi de suite étaient toujours de nature mono-thread)
Bien qu'il s'agisse d'une programmation multi-thread
Mais nous n'avons pas à nous soucier du multi -problèmes de threading rencontrés par les langages multithread traditionnels​​C, Java, etc.
Jetons un coup d'oeil à ce qu'est Web Worker

Dedicated Worker

Dedicated Worker (Dedicated Worker Worker) est le Web Worker le plus couramment utilisé
Et chaque navigateur l'implémente bien

Déclaration

Quand avons-nous besoin du multithreading Par exemple, si on a besoin de calculs complexes,

//demo.jsfunction calculate(){
  var ret = 0;  for(var i = 1; i <= 1e9; i++){
    ret += i;
  }  return ret;
}var result;var start;var end;
start = +new Date();
result = calculate();
end = +new Date();
console.log(result); //500000000067109000console.log(end - start); //977
On calcule la valeur de 1 à 1 milliard

Arrête le rendu de la page pendant près d'1 seconde
C'est assez hostile au expérience utilisateur
Bien qu'il n'y ait pas de calculs aussi fous dans le développement
Mais nous pouvons rencontrer des tâches intensives et complexes
À ce stade, nous voudrons peut-être ouvrir un nouveau fil de discussion indépendant pour terminer
Et nous n'avons besoin que de faire attention à la valeur du résultat


HTML5 nous permet d'utiliser des threads de travail

Son contenu de travail doit être écrit dans un fichier js séparé
Laissez nos multiples blocs de programme s'exécuter simultanément

var worker = new Worker(&#39;scripts/worker.js&#39;);
Instancié de cette manière Un paramètre worker

est le chemin d'accès au fichier js (le fichier HTML principal et le fichier Worker doivent respecter la même politique d'origine)
Lorsque le programme s'exécute ici
ce fichier sera chargé dans un Worker
Parcourir Le serveur démarrera un thread indépendant pour exécuter le fichier js

Interaction

Notre thread principal et notre thread de travail interagissent en fonction du mécanisme d'événement

En d'autres termes,
Ils doivent tous s'abonner à des événements pour communiquer entre eux (événement onmessage)

//主线程
worker.addEventListener(&#39;message&#39;, function(e){
    //e.data为从worker线程得到的数据
});
worker.possMessage(...);//向worker线程发送数据
//工作线程
addEventListener(&#39;message&#39;, function(e){
    //e.data为从主线程得到的数据
});
possMessage(...);//向主线程发送数据
Leur liaison de données est similaire à l'envoi de données

sauf qu'il n'est pas nécessaire d'appeler l'API avec un objet dans le fichier du travailleur
De cette façon, le calcul complexe que nous venons de faire peut être effectué par le travailleur

//worker.jsfunction calculate(){
  var ret = 0;  for(var i = 1; i <= 1e9; i++){
    ret += i;
  }  return ret;
}
postMessage(calculate());
//demo.jsvar worker = new Worker(&#39;scripts/worker.js&#39;);
worker.addEventListener('message', function(e){
  console.log(e.data); //500000000067109000}, false);
Dans le HTML5 Spécification Web Worker, le

travailleur peut également instancier son propre travailleur (cela ne semble rien de nécessaire)
Sous-travailleur appelé (thread imbriqué)
Cependant, je l'ai testé et Chrome ne prend pas encore en charge le sous-travailleur
Mais on dit que Firefox prend en charge la

la résiliation

Puisque nous pouvons créer un travailleur

alors nous devrions également pouvoir mettre fin au travailleur pour arrêter de travailler
Il peut être résilié dans à la fois le thread principal et le thread de travail
Appelez simplement l'API dans l'objet travailleur ou la portée du travailleur
L'une est que nous le laissons terminer son travail
L'autre est qu'il frappe tout seul

//主线程worker.terminate();
//工作线程close();
Mais je pense que nous

y mettrons généralement fin en appelant la méthode de terminaison sur l'objet travailleur
Ce sera plus sûr

Environnement

Je l'ai dit au début

On n'a pas à se soucier des problèmes multi-thread rencontrés par les langages multi-thread traditionnels
Par exemple Introduit pour éviter qu'ils ne s'emparent des ressources...
Incroyablement complexe mécanisme de verrouillage
Pourquoi ?
Parce qu'à l'intérieur du travailleur
nous ne pouvons accéder à aucune ressource du programme principal
Il s'agit d'un fil complètement indépendant
Web Worker a les restrictions suivantes :

  • Restrictions liées aux règles de même origine

  • Impossible d'accéder à la page DOM et aux autres ressources

  • La mise en œuvre du navigateur est différente

Mais nous pouvons faire ces choses à l'intérieur du travailleur :

  • Peut effectuer des opérations réseau (Ajax, Web Sockets)

  • Peut utiliser timing (set/clearTimeout(), set/clearInterval())

  • Accéder aux copies de certaines variables et fonctions globales importantes (navigateur, emplacement, JSON, applicationCache)

  • Vous pouvez utiliser importScrips() pour charger des scripts js supplémentaires

importScripts(&#39;foo.js&#39;,&#39;bar.js&#39;);importScripts(&#39;foobar.js&#39;);
Si vous êtes curieux, vous pouvez voir sa portée dans le travailleur

console.log(this); Quelles sont les

applications

À propos de son application

Nous utiliserons Web Worker pour faire ces choses

  • Calculs mathématiques complexes

  • Tri de données complexes

  • Traitement des données (compression, traitement d'images...)

  • Réseau à fort trafic communication

Shared Worker

En plus du fil de discussion dédié, il existe également un fil de discussion partagé Shared Worker

Vous pouvez en prendre connaissance
Je viens de vérifier il
Jusqu'à présent, seuls Google, Firefox et Open ont implémenté cette technologie


Si notre site Web ou notre application peut charger plusieurs onglets (onglets) en même temps temps

alors si nous utilisons des travailleurs ordinaires, nous pouvons créer plusieurs threads à plusieurs reprises
Cela occupera inévitablement des ressources système
À ce stade, ce serait formidable si nous pouvions autoriser les instances d'application ou de page de l'ensemble du site pour partager un travailleur
~
Les threads partagés et les threads dédiés s'utilisent de la même manière, juste un peu plus compliqué

var worker = new SharedWorker(&#39;scripts/worker.js&#39;);

由于共享线程需要与多个程序实例或页面链接
所以它需要通过某种方式来了解消息的来源
这个方式就是利用一个唯一标识符port(端口)
这样我们刚才的例子就需要写成这个样子

//demo.jsvar worker = new SharedWorker(&#39;scripts/worker.js&#39;);
worker.port.addEventListener('message', function(e){
  console.log(e.data); //500000000067109000}, false);
worker.port.start();

在主线程中
端口连接必须初始化
使用API worker.port.start();

//worker.jsfunction calculate(){
  var ret = 0;  for(var i = 1; i <= 1e9; i++){
    ret += i;
  }  return ret;
}
addEventListener(&#39;connect&#39;, function(e){
  var port = e.ports[0];
  port.start();
  port.postMessage(calculate());
});

在共享worker内部同样需要初始化端口连接port.start();
除此之外,我们还需要处理额外事件onconnect
这个事件为我们的特定连接提供了端口对象
var port = e.ports[0];用于获取连接分配的端口


我们的onmessage事件就可以写在onconnect事件处理函数内部

addEventListener(&#39;connect&#39;, function(e){
  var port = e.ports[0];
  port.addEventListener(&#39;message&#39;, function(e){    ...
    port.postMessage(...);    ...
  });
  port.start();
});

除此之外,其他的功能共享Worker和专用Worker都是一样的

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn