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.
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.
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 :
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>
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 :
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 :
共享 Workers 在同一源(origin)下面的各种进程都可以访问它,包括:iframes、浏览器中的不同tab页(一个tab页就是一个单独的进程,所以Shared Workers可以用来实现 tab 页之间的交流)、以及其他的共享 Workers。以下是浏览器支持的情况:
Service Worker 功能:
在目前阶段,Service Worker 的主要能力集中在网络代理和离线缓存上。具体的实现上,可以理解为 Service Worker 是一个能在网页关闭时仍然运行的 Web Worker。以下是浏览器支持的情况:
本文主要讨论 专用 Workers,没有特别声明的话,Web Workers、Workers都是指代的专用 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 和创建它的页面之间进行通信,需要使用 postMessage
方法或 Broadcast Channel。
新浏览器支持JSON对象作为方法的第一个参数,而旧浏览器只支持字符串。
来看一个示例,通过将 JSON 对象作为一个更“复杂”的示例传递,创建 Worker 的页面如何与之通信。传递字符串跟传递对象的方式也是一样的。
让我们来看看下面的 HTML 页面(或者更准确地说是它的一部分):
<button>Start computation</button> <script> function startComputation() { worker.postMessage({'cmd': 'average', 'data': [1, 2, 3, 4]}); } var worker = new Worker('doWork.js'); worker.addEventListener('message', 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 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:
Broadcast Channel 浏览器支持比较有限:
有两种方式发送消息给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 :
importScripts()
pour importer des scripts externesMalheureusement, les Web Workers n'ont pas accès à certaines fonctionnalités JavaScript très critiques :
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.
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 :
Les exemples sont les suivants :
Dans Ici, vous pouvez voir que nous avons créé un travailleur et commencé à écouter les événements d'erreur.
À 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.
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 :
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!