I Web Worker in JavaScript
Questo articolo spiega cosa sono i Web Worker in JavaScript.
YouTube Video
javascript-web-worker.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>JavaScript & HTML</title>
6 <style>
7 * {
8 box-sizing: border-box;
9 }
10
11 body {
12 margin: 0;
13 padding: 1em;
14 padding-bottom: 10em;
15 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16 background-color: #f7f9fc;
17 color: #333;
18 line-height: 1.6;
19 }
20
21 .container {
22 max-width: 800px;
23 margin: 0 auto;
24 padding: 1em;
25 background-color: #ffffff;
26 border: 1px solid #ccc;
27 border-radius: 10px;
28 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
29 }
30
31 .container-flex {
32 display: flex;
33 flex-wrap: wrap;
34 gap: 2em;
35 max-width: 1000px;
36 margin: 0 auto;
37 padding: 1em;
38 background-color: #ffffff;
39 border: 1px solid #ccc;
40 border-radius: 10px;
41 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
42 }
43
44 .left-column, .right-column {
45 flex: 1 1 200px;
46 min-width: 200px;
47 }
48
49 h1, h2 {
50 font-size: 1.2rem;
51 color: #007bff;
52 margin-top: 0.5em;
53 margin-bottom: 0.5em;
54 border-left: 5px solid #007bff;
55 padding-left: 0.6em;
56 background-color: #e9f2ff;
57 }
58
59 button {
60 display: block;
61 margin: 1em auto;
62 padding: 0.75em 1.5em;
63 font-size: 1rem;
64 background-color: #007bff;
65 color: white;
66 border: none;
67 border-radius: 6px;
68 cursor: pointer;
69 transition: background-color 0.3s ease;
70 }
71
72 button:hover {
73 background-color: #0056b3;
74 }
75
76 #output {
77 margin-top: 1em;
78 background-color: #1e1e1e;
79 color: #0f0;
80 padding: 1em;
81 border-radius: 8px;
82 min-height: 200px;
83 font-family: Consolas, monospace;
84 font-size: 0.95rem;
85 overflow-y: auto;
86 white-space: pre-wrap;
87 }
88
89 .highlight {
90 outline: 3px solid #ffc107; /* yellow border */
91 background-color: #fff8e1; /* soft yellow background */
92 transition: background-color 0.3s ease, outline 0.3s ease;
93 }
94
95 .active {
96 background-color: #28a745; /* green background */
97 color: #fff;
98 box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
99 transition: background-color 0.3s ease, box-shadow 0.3s ease;
100 }
101 </style>
102</head>
103<body>
104 <div class="container">
105 <h1>JavaScript Console</h1>
106 <button id="executeBtn">Execute</button>
107 <div id="output"></div>
108 </div>
109
110 <script>
111 // Override console.log to display messages in the #output element
112 (function () {
113 // Override console.log
114 const originalLog = console.log;
115 console.log = function (...args) {
116 originalLog.apply(console, args);
117 const message = document.createElement('div');
118 message.textContent = args.map(String).join(' ');
119 output.appendChild(message);
120 };
121
122 // Override console.error
123 const originalError = console.error;
124 console.error = function (...args) {
125 originalError.apply(console, args);
126 const message = document.createElement('div');
127 message.textContent = args.map(String).join(' ');
128 message.style.color = 'red'; // Color error messages red
129 output.appendChild(message);
130 };
131 })();
132
133 document.getElementById('executeBtn').addEventListener('click', () => {
134 // Prevent multiple loads
135 if (document.getElementById('externalScript')) return;
136
137 const script = document.createElement('script');
138 script.src = 'javascript-web-worker.js';
139 script.id = 'externalScript';
140 //script.onload = () => console.log('javascript-web-worker.js loaded and executed.');
141 //script.onerror = () => console.log('Failed to load javascript-web-worker.js.');
142 document.body.appendChild(script);
143 });
144 </script>
145</body>
146</html>
Web Worker
in JavaScript
Web Worker
in JavaScript è un meccanismo che consente al codice di essere eseguito in un thread separato dal thread principale. Questo consente di eseguire calcoli complessi e operazioni di lunga durata in modo asincrono, evitando il blocco del thread principale. Usando i Web Worker
, la reattività dell'interfaccia utente migliora e le prestazioni dell'applicazione aumentano.
L'uso di base dei Web Worker
Vediamo l'utilizzo di base di Web Worker
.
Un nuovo Web Worker
viene creato specificando un file JavaScript.
1// worker.js (created as a separate file)
2onmessage = function(event) {
3 // Receive a message
4 const data = event.data;
5 // Perform heavy computation or processing
6 const result = data * 2;
7 // Return the result to the main thread
8 postMessage(result);
9};
1// Main thread (main.js)
2const worker = new Worker('worker.js');
3
4// Send a message to the worker
5worker.postMessage(10);
6
7// Receive a message from the worker
8worker.onmessage = function(event) {
9 console.log('Result from Worker: ', event.data); // Result: 20
10};
11
12// Error handling
13worker.onerror = function(error) {
14 console.error('Worker error: ', error);
15};
- Questo codice dimostra il meccanismo di base per utilizzare un
Web Worker
per richiedere un calcolo dal thread principale e ricevere il risultato in modo asincrono. Invia10
come messaggio alWeb Worker
e riceve20
come messaggio di risultato. Il thread principale e ilWeb Worker
comunicano inviando e ricevendo messaggi per richiedere e ottenere i risultati dell'elaborazione.
Funzioni di base
Web Worker
offre le seguenti funzionalità di base.
postMessage
eonmessage
Utilizzato per inviare e ricevere messaggi tra il thread principale e ilWeb Worker
. Invia dati conpostMessage
e ricevili cononmessage
.- Indipendenza del Thread
Web Worker
funziona in modo completamente indipendente dal thread principale. Di conseguenza, non è possibile accedere alle variabili e alle funzioni definite nel thread principale. I dati richiesti devono essere passati tramitepostMessage
. - Importazione di Script
Per caricare script esterni all'interno di un
Web Worker
, utilizzareimportScripts()
.
1// mathUtils.js
2function double(n) {
3 return n * 2;
4}
1// worker.js
2importScripts('mathUtils.js');
3
4onmessage = function(event) {
5 const input = event.data;
6 const result = double(input); // mathUtils.jsの関数を使用
7 postMessage(result);
8};
1// Main thread (main.js)
2const worker = new Worker('worker.js');
3
4// Send a message to the worker
5worker.postMessage(10);
6
7// Receive a message from the worker
8worker.onmessage = function(event) {
9 console.log('Result from Worker: ', event.data); // Result: 20
10};
11
12// Error handling
13worker.onerror = function(error) {
14 console.error('Worker error: ', error);
15};
In alternativa, è possibile utilizzare anche import
come mostrato di seguito.
1// lib.js
2
3// Simulated CPU-intensive task
4export function doHeavyWork(n) {
5 return n * 2;
6}
1// worker.js
2import { doHeavyWork } from './lib.js';
3
4self.onmessage = (event) => {
5 const data = event.data;
6 const result = doHeavyWork(data);
7 self.postMessage(result);
8};
1// Main thread (main.js)
2const worker = new Worker('worker.js', { type: 'module' });
3
4// Send a message to the worker
5worker.postMessage(10);
6
7// Receive a message from the worker
8worker.onmessage = function(event) {
9 console.log('Result from Worker: ', event.data); // Result: 20
10};
11
12// Error handling
13worker.onerror = function(error) {
14 console.error('Worker error: ', error);
15};
- Specificando
type: 'module'
nell'argomento dinew Worker
, è possibile trattare il worker come un modulo ES e utilizzare la sintassiimport
.
Differenze tra Web Worker
e funzioni async
Web Worker
Caratteristiche
- Isolamento del Thread
Web Worker
esegue il codice JavaScript in un thread separato. Questo consente di eseguire elaborazioni di calcolo pesanti senza bloccare il thread principale (thread UI). - Elaborazione Concorrente
Usare
Web Worker
permette ai programmi JavaScript di eseguire elaborazioni concorrenti su più thread. - Comunicazione tramite Messaggi
Il
Web Worker
e il thread principale non condividono direttamente i dati e scambiano messaggi tramitepostMessage
eonmessage
. - Impossibile Accedere alla UI
Web Worker
non può accedere al DOM, quindi non può manipolare direttamente l'interfaccia utente (UI).
Casi d'uso
- È adatto per processi di calcolo pesante come l'elaborazione delle immagini, l'analisi dei dati e la crittografia.
- Può essere utilizzato quando non si desidera bloccare il thread principale.
async
Caratteristiche
- Semplificazione dell'Elaborazione Asincrona
La funzione
async
è una sintassi per rendere più leggibile l'elaborazione asincrona, utilizzando internamentePromise
. - Thread Singolo
Tutte le funzioni
async
vengono eseguite sul thread principale. Pertanto, è necessario trovare soluzioni per evitare di bloccare il thread UI. - Ottimale per Operazioni di I/O È adatto per attività asincrone come comunicazione di rete e lettura di file, ma non per calcoli pesanti.
Casi d'uso
- È adatto per la comunicazione di rete come le chiamate API.
- È adatto per la lettura e scrittura di file tramite API del browser o Node.js.
Differenze principali
Caratteristiche | Web Worker | async |
---|---|---|
Ambiente di esecuzione | Thread separato | Thread principale |
Scopo | Elaborazione parallela, gestione di calcoli intensivi | Descrizione concisa delle operazioni asincrone |
Accesso al DOM | Non possibile | Possibile |
Metodo di comunicazione | Passaggio di messaggi (es. postMessage ) |
Non richiesto (gestito tramite chiamate di funzione dirette o await ) |
Casi d'uso | Calcoli a lungo termine, analisi dei dati | Operazioni di I/O, chiamate API |
Quando utilizzare ciascuno
Per compiti che richiedono un utilizzo intensivo della CPU, è possibile utilizzare i Web Worker
per ridurre il carico sul thread principale. D'altro canto, per la comunicazione di rete o le operazioni di I/O, è possibile semplificare il codice utilizzando async
/await
.
Combinandoli in modo appropriato, è possibile ottenere un'elaborazione asincrona efficiente.
Esempi di utilizzo di Web Worker
Esempio di trasferimento di calcoli complessi
Di seguito è riportato un esempio di delega dei calcoli pesanti.
1// worker.js
2onmessage = function(event) {
3 const num = event.data;
4 const result = fibonacci(num);
5 postMessage(result);
6};
7
8function fibonacci(n) {
9 if (n <= 1) return n;
10 return fibonacci(n - 1) + fibonacci(n - 2);
11}
1// Main thread
2const worker = new Worker('worker.js');
3
4worker.onmessage = function(event) {
5 console.log('Fibonacci result: ', event.data);
6};
7
8worker.postMessage(40); // Delegate heavy computation to the worker
- Questo codice è un esempio di utilizzo di un Web Worker per separare ed eseguire attività pesanti, come il calcolo della sequenza di Fibonacci, dal thread principale.
Un esempio di specifica del nome di un compito
Segue un esempio di invio e ricezione di messaggi specificando il nome di un compito.
1// worker.js
2self.onmessage = function(event) {
3 switch (event.data.task) {
4 case 'add':
5 const result = event.data.a + event.data.b;
6 self.postMessage({ task: 'result', value: result });
7 break;
8 default:
9 self.postMessage({ task: 'error', message: 'Invalid Task' });
10 }
11};
1// Main thread
2const worker = new Worker('worker.js');
3
4worker.onmessage = function(event) {
5 switch (event.data.task) {
6 case 'result':
7 console.log('Task result: ', event.data.value);
8 break;
9 case 'error':
10 console.error('Error: ', event.data.message);
11 break;
12 }
13};
14
15worker.postMessage({ task: 'add', a: 10, b: 20 });
- Questo codice è un esempio di elaborazione in base al nome del
task
nel messaggio, in cui ilWeb Worker
restituisce i risultati del calcolo o eventuali errori al thread principale insieme al nome del compito.
Note
Quando si utilizza Web Worker
, tenere presenti i seguenti punti.
- Impossibile Accedere al DOM
Web Worker
non può manipolare l'interfaccia utente né accedere al DOM. La manipolazione del DOM deve essere eseguita nel thread principale. - Overhead della Comunicazione
C'è un certo overhead quando si scambiano dati tra il thread principale e il
Web Worker
. Questo può influire sulle prestazioni, specialmente quando si scambiano grandi quantità di dati frequentemente. - Politica della Stessa Origine
Gli script
Web Worker
sono soggetti alla politica della stessa origine. Gli script non possono essere caricati da domini diversi.
L'uso dei Web Worker
può migliorare le prestazioni e la reattività della tua applicazione, ma è importante utilizzarli in modo appropriato considerando limitazioni come l'impossibilità di manipolare il DOM.
Puoi seguire l'articolo sopra utilizzando Visual Studio Code sul nostro canale YouTube. Controlla anche il nostro canale YouTube.