Maison  >  Article  >  interface Web  >  Les éléments constitutifs de JavaScript Web Workers et 5 scénarios d'utilisation

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios d'utilisation

coldplay.xixi
coldplay.xixiavant
2020-12-04 15:03:281939parcourir

Il s'agit d'une série d'articles dans la colonne JavaScript dédiés à l'exploration du javascript et des composants qu'il construit.

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios d'utilisation

Recommandations d'apprentissage gratuites associées : javascript (vidéo)

Cette fois, nous allons étape par étape, expliquez les Web Workers, d'abord un concept simple, puis discutez des différents types de Web Workers et de la manière dont leurs composants fonctionnent ensemble. , ainsi que leurs avantages et limites respectifs dans différents scénarios. Enfin, fournissez 5 scénarios pour une utilisation correcte des Web Workers.

Comme nous l'avons évoqué dans l'article précédent, il faut savoir que le langage JavaScript utilise un modèle mono-thread. Cependant, JavaScript offre également aux développeurs la possibilité d'écrire du code asynchrone.

Limitations de la programmation asynchrone

Les articles précédents traitaient de la programmation asynchrone et du moment où vous devez l'utiliser.

La programmation asynchrone peut rendre l'interface de l'interface utilisateur réactive (vitesse de rendu rapide). Grâce à la "planification de code", le code qui doit demander du temps est placé dans la boucle d'événements puis exécuté plus tard, permettant ainsi à l'interface utilisateur de restituer. afficher en premier.

Un bon cas d'utilisation pour la programmation asynchrone est celui des requêtes AJAX. Étant donné que les requêtes peuvent prendre beaucoup de temps, vous pouvez utiliser des requêtes asynchrones, qui permettent à d'autres codes de s'exécuter pendant que le client attend une réponse.

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios dutilisation

Cependant, cela soulève un problème : la requête est gérée par l'API WEB du navigateur, mais comment rendre un autre code asynchrone Par exemple, s'il réussit Le code dans ? le rappel consomme beaucoup de CPU :

var result = performCPUIntensiveCalculation();

Si performCPUIntensiveCalculation n'est pas une requête HTTP mais un code bloquant (comme une boucle for avec beaucoup de contenu), il n'y a aucun moyen d'effacer la boucle d'événement à temps, et le rendu UI du navigateur sera bloqué et la page ne pourra pas répondre à l'utilisateur à temps.

Cela signifie que les fonctions asynchrones ne peuvent résoudre qu'une petite partie des limitations du monothreading dans le langage JavaScript.

Dans certains cas, vous pouvez utiliser setTimeout pour bloquer les calculs de longue durée, et vous pouvez utiliser setTimeout pour le mettre temporairement dans la file d'attente asynchrone afin de permettre à la page d'être rendue plus rapidement. Par exemple, en regroupant des calculs complexes dans des setTimeout appels distincts, vous pouvez les placer dans des "spots" distincts dans la boucle d'événements, gagnant ainsi du temps d'exécution pour que l'interface utilisateur rendu/réponse.

Regardez une fonction simple qui calcule la moyenne d'un tableau de nombres :

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios dutilisation

Voici comment réécrire le code ci-dessus et « simuler » l'asynchronicité :

function averageAsync(numbers, callback) {
    var len = numbers.length,
        sum = 0;

    if (len === 0) {
        return 0;
    } 

    function calculateSumAsync(i) {
        if (i <p>Utilisez la fonction setTimeout qui ajoutera chaque étape du calcul plus loin dans la boucle d'événements. Entre chaque calcul, il y aura suffisamment de temps pour que d'autres calculs se produisent, permettant ainsi au navigateur d'effectuer le rendu. </p><h2>Web Worker peut résoudre ce problème </h2><p>HTML5 nous apporte beaucoup de nouveautés, notamment : </p>
  • SSE (que nous avons déjà évoqué dans l'article précédent décrit et comparé aux WebSockets)
  • Géolocalisation
  • Cache d'application
  • Stockage local
  • Glisser-Déposer
  • Web Workers

Présentation de Web Worker

Le rôle de Web Worker est de créer un environnement multithread pour JavaScript, permettant au thread principal de créer des threads de travail et d'attribuer certaines tâches à ces derniers. pour l'exécution. Pendant que le thread principal est en cours d'exécution, le thread de travail s'exécute en arrière-plan et les deux n'interfèrent pas l'un avec l'autre. Attendez que le thread de travail termine la tâche de calcul, puis renvoie le résultat au thread principal. L'avantage de ceci est que certaines tâches gourmandes en calcul ou à latence élevée sont surchargées par le thread de travail, et le thread principal (généralement responsable de l'interaction avec l'interface utilisateur) sera fluide et ne sera ni bloqué ni ralenti.

Vous vous demandez peut-être : "JavaScript n'est-il pas un langage à thread unique ?"

En fait, JavaScript est un langage qui ne définit pas de modèle de thread. Les Web Workers ne font pas partie de JavaScript, mais sont des fonctionnalités de navigateur accessibles via JavaScript. Historiquement, la plupart des navigateurs étaient monothread (bien sûr, cela a changé) et la plupart des implémentations de JavaScript se produisaient dans le navigateur. Les Web Workers ne sont pas implémentés dans Node.JS. Il existe des concepts similaires de cluster et child_process dans Node.js. Ils sont également multithread mais sont toujours différents des Web Workers.

Il convient de noter qu'il existe trois types de Web Workers mentionnés dans la spécification :

  • Dedicated Workers (Dedicated Workers)
  • Shared Workers (Shared Workers)
  • Service Workers (Service Workers)

Dedicated Workers

Les Dedicated Workers ne sont accessibles que par la page qui les a créés et ne peuvent communiquer qu'avec elle. Voici ce que les navigateurs prennent en charge :

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios dutilisation

Shared Workers

共享 Workers 在同一源(origin)下面的各种进程都可以访问它,包括:iframes、浏览器中的不同tab页(一个tab页就是一个单独的进程,所以Shared Workers可以用来实现 tab 页之间的交流)、以及其他的共享 Workers。以下是浏览器支持的情况:

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios dutilisation

Service workers

Service Worker 功能:

  • 后台消息传递
  • 网络代理,转发请求,伪造响应
  • 离线缓存
  • 消息推送

在目前阶段,Service Worker 的主要能力集中在网络代理和离线缓存上。具体的实现上,可以理解为 Service Worker 是一个能在网页关闭时仍然运行的 Web Worker。以下是浏览器支持的情况:

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios dutilisation

本文主要讨论 专用 Workers,没有特别声明的话,Web Workers、Workers都是指代的专用 Workers。

Web Workers 是如何工作

Web Workers 一般通过脚本为 .js 文件来构建,在页面中还通过了一些异步的 HTTP 请求,这些请求是完全被隐藏了的,你只需要调用 Web Worker API.

Worker 利用类线程间消息传递来实现并行性。它们保证界面的实时性、高性能和响应性呈现给用户。

Web Workers 在浏览器中的一个独立线程中运行。因此,它们执行的代码需要包含在一个单独的文件中。这一点很重要,请记住!

让我们看看基本 Workers 是如何创建的:

var worker = new Worker('task.js');

Worker() 构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务。由于 Worker 不能读取本地文件,所以这个脚本必须来自网络。如果下载没有成功(比如404错误),Worker 就会默默地失败。

为了启动创建的 Worker,需要调用 postMessage 方法:

worker.postMessage();

Web Worker 通信

为了在 Web Worker 和创建它的页面之间进行通信,需要使用 postMessage 方法或 Broadcast Channel。

postMessage 方法

新浏览器支持JSON对象作为方法的第一个参数,而旧浏览器只支持字符串。

来看一个示例,通过将 JSON 对象作为一个更“复杂”的示例传递,创建 Worker 的页面如何与之通信。传递字符串跟传递对象的方式也是一样的。

让我们来看看下面的 HTML 页面(或者更准确地说是它的一部分):

<button>Start computation</button>

<script>
  function startComputation() {
    worker.postMessage({&#39;cmd&#39;: &#39;average&#39;, &#39;data&#39;: [1, 2, 3, 4]});
  }
  var worker = new Worker(&#39;doWork.js&#39;);
  worker.addEventListener(&#39;message&#39;, function(e) {
    console.log(e.data);
  }, false);
  
</script>

然后这是 worker 中的 js 代码:

self.addEventListener('message', function(e) {
  var data = e.data;
  switch (data.cmd) {
    case 'average':
      var result = calculateAverage(data); // 从数值数组中计算平均值的函数
      self.postMessage(result);
      break;
    default:
      self.postMessage('Unknown command');
  }
}, false);

当单击该按钮时,将从主页调用 postMessage。postMessage 行将 JSON 对象传给Worker。Worker 通过定义的消息处理程序监听并处理该消息。

当消息到达时,实际的计算在worker中执行,而不会阻塞事件循环。Worker 检查传递的事件参数 e,像执行 JavaScript 函数一样,处理完成后,把结果传回给主页。

在 Worker 作用域中,this 和 self 都指向 Worker 的全局作用域。

有两种方法可以停止 Worker:从主页调用 worker.terminate() 或在 worker 内部调用 self.close()

Broadcast Channel

Broadcast Channel API 允许同一原始域和用户代理下的所有窗口,iFrames 等进行交互。也就是说,如果用户打开了同一个网站的的两个标签窗口,如果网站内容发生了变化,那么两个窗口会同时得到更新通知。

还是不明白?就拿 Facebook 作为例子吧,假如你现在已经打开 了Facebook 的一个窗口,但是你此时还没有登录,此时你又打开另外一个窗口进行登录,那么你就可以通知其他窗口/标签页去告诉它们一个用户已经登录了并请求它们进行相应的页面更新。

// Connection to a broadcast channel
var bc = new BroadcastChannel('test_channel');

// Example of sending of a simple message
bc.postMessage('This is a test message.');

// Example of a simple event handler that only
// logs the message to the console
bc.onmessage = function (e) { 
  console.log(e.data); 
}

// Disconnect the channel
bc.close()

可以从下面这张图,在视觉上来清晰地感受 Broadcast Channel:

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios dutilisation

Broadcast Channel 浏览器支持比较有限:

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios dutilisation

消息的大小

有两种方式发送消息给Web Workers:

  • Copier le message  : Le message est sérialisé, copié, envoyé, puis désérialisé à l'autre extrémité. La page et le Worker ne partagent pas la même instance, le résultat final est donc qu'une copie est créée pour chaque passage. La plupart des navigateurs utilisent JSON pour encoder et décoder la valeur des deux côtés, de sorte que les opérations de décodage et d'encodage des données sont. forcément, cela augmentera le temps nécessaire au processus de transmission des messages. Plus le message est volumineux, plus son envoi prendra du temps.
  • Délivrer le message : Cela signifie que l'expéditeur d'origine ne peut plus l'utiliser une fois qu'il a été envoyé. La transmission des données est quasi instantanée. La limitation de cette méthode de transmission est qu'elle ne peut être transférée qu'en utilisant le type ArrayBuffer.

Fonctionnalités disponibles avec Web Workers

En raison de la nature multithread de JavaScript, les Web Workers n'ont accès qu'à un sous-ensemble de fonctionnalités JavaScript. Voici quelques-unes de ses fonctionnalités :

Les Web Workers ne peuvent accéder qu'à un sous-ensemble de fonctionnalités JavaScript en raison de leur nature multithread. Voici une liste des propriétés disponibles :

  • objet navigateur
  • objet de localisation (lecture seule)
  • MLHttpRequest
  • setTimeout()/ clearTimeout() et setInterval()/clearInterval()
  • Application Cache
  • Utilisez importScripts() pour importer des scripts externes
  • Créer d'autres Web Workers

Limitations des Web Workers

Malheureusement, les Web Workers n'ont pas accès à certaines fonctionnalités JavaScript très critiques :

  • DOM (ce qui rend les threads dangereux)
  • objet fenêtre
  • objet document
  • objet parent

Cela signifie que le Web Worker ne peut pas manipuler le DOM (et donc l'interface utilisateur). Cela peut parfois être délicat, mais une fois que vous aurez compris comment utiliser correctement les Web Workers, vous commencerez à les utiliser comme des « ordinateurs » distincts et toutes les modifications de l'interface utilisateur se produiront dans le code de votre page. Les travailleurs feront tout le gros du travail pour vous, puis renverront les résultats sur la page une fois terminés.

Gestion des erreurs

Tout comme le code JavaScript, vous devez également gérer les erreurs générées par les travailleurs Web. Si une erreur est rencontrée lors de l'exécution de Worker, un événement ErrorEvent sera déclenché. L'interface contient trois propriétés utiles pour aider à résoudre les problèmes :

  • filename - provoque le nom de script du Worker
  • lineno - se produit Numéro de ligne d'erreur
  • message - Description de l'erreur

Les exemples sont les suivants :

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios dutilisation

Dans Ici, vous pouvez voir que nous avons créé un travailleur et commencé à écouter les événements d'erreur.

Les éléments constitutifs de JavaScript Web Workers et 5 scénarios dutilisation

À l'intérieur du travailleur (dans workerWithError.js ) nous créons une exception en multipliant l'indéfini x par 2. L'exception est propagée au script initial, puis l'événement d'erreur est surveillé via la page pour capturer l'erreur.

5 bons exemples d'applications de Web Workers

Jusqu'à présent, nous avons répertorié les avantages et les limites des Web Workers. Voyons maintenant quels sont leurs cas d'utilisation les plus puissants :

  • Ray tracing (ray tracing)  : Le ray tracing est une technologie de rendu qui trace le chemin de la lumière pour générer des images en unités de pixels. Le lancer de rayons utilise des calculs mathématiques gourmands en CPU pour simuler le trajet de la lumière. L'idée est de simuler certains effets comme la réflexion, la réfraction, les matériaux, etc. Toute cette logique de calcul peut être ajoutée au Web Worker pour éviter de bloquer le thread de l'interface utilisateur. Mieux encore : le rendu des images peut être facilement réparti entre plusieurs travailleurs (et sur plusieurs processeurs). Voici une démo simple du lancer de rayons à l'aide de Web Workers - https://nerget.com/rayjs-mt/r... .
  • Chiffrement : Le chiffrement de bout en bout devient de plus en plus populaire en raison de réglementations de plus en plus strictes sur les données personnelles et sensibles. Le cryptage prend beaucoup de temps, surtout si de nombreuses données doivent être cryptées fréquemment (par exemple, avant d'être envoyées au serveur). C'est un excellent scénario pour utiliser un Web Worker car il ne nécessite pas d'accès au DOM ou à quoi que ce soit d'extraordinaire - c'est un pur algorithme qui fait son travail. Tant que vous travaillez dans Web Worker, cela sera transparent pour les utilisateurs finaux et n'affectera pas l'expérience.
  • Prélecture des données : Afin d'optimiser votre site Web ou votre application Web et d'améliorer le temps de chargement des données, vous pouvez utiliser Web Workers pour charger et stocker certaines données à l'avance afin qu'elles puissent être chargées lorsque devait être utilisé plus tard. Les Web Workers sont parfaits dans ce cas car ils n'affectent pas l'interface utilisateur de l'application, contrairement aux cas où les Workers ne sont pas utilisés.
  • Applications Web progressives : Ce type d'application Web progressive nécessite qu'elle puisse se charger rapidement, même dans des conditions de réseau utilisateur instables. Cela signifie que les données doivent être stockées localement dans le navigateur. C'est également là qu'IndexDB ou des API similaires entrent en jeu. Normalement, le stockage côté client est nécessaire, mais s'il est utilisé sans bloquer le thread de rendu de l'interface utilisateur, le travail doit être effectué dans Worker. Cependant, en prenant IndexDB comme exemple, il fournit des API asynchrones, et vous n'avez pas besoin d'utiliser un web worker pour les appeler. Cependant, s'il s'agit d'une API synchrone, elle doit être utilisée dans un Worker.
  • Vérification orthographique : Le flux de travail d'un programme de vérification orthographique de base est le suivant : le programme lit un fichier de dictionnaire avec une liste de mots correctement orthographiés. Le dictionnaire est analysé dans un arbre de recherche pour rendre les recherches de texte réelles plus efficaces. Lorsqu'un mot est fourni au vérificateur, le programme vérifie s'il existe dans un arbre de recherche prédéfini. Si le mot n'est pas trouvé dans l'arborescence, vous pouvez proposer à l'utilisateur une orthographe alternative en remplaçant le caractère de remplacement et en testant s'il s'agit d'un mot valide s'il s'agit du mot que l'utilisateur souhaitait écrire. Tous ces processus peuvent être effectués dans Web Worker. Les utilisateurs peuvent saisir des mots et des phrases sans être bloqués. Le Web Worker vérifie si les mots sont corrects en arrière-plan et propose des mots alternatifs.

Si vous souhaitez en savoir plus sur la programmation, merci de faire attention à la formation php rubrique !

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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer