Web Workers i JavaScript
Den här artikeln förklarar Web Workers i 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
i JavaScript
Web Worker
i JavaScript är en mekanism som gör det möjligt att köra kod i en separat tråd från huvudtråden. Detta möjliggör tunga beräkningar och långvariga operationer att utföras asynkront, vilket förhindrar att huvudtråden blockeras. Genom att använda Web Worker
förbättras användargränssnittets responsivitet och applikationens prestanda.
Grundläggande användning av Web Worker
Låt oss titta på den grundläggande användningen av Web Worker
.
En ny Web Worker
skapas genom att ange en JavaScript-fil.
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};
- Denna kod demonstrerar den grundläggande mekanismen för att använda en
Web Worker
för att begära beräkning från huvudtråden och ta emot resultatet asynkront. Den skickar10
som ett meddelande tillWeb Worker
och tar emot20
som resultatmeddelande. Huvudtråden ochWeb Worker
kommunicerar genom att skicka och ta emot meddelanden för att begära och ta emot bearbetningsresultat.
Grundläggande funktioner
Web Worker
erbjuder följande grundläggande funktioner.
postMessage
ochonmessage
Används för att skicka och ta emot meddelanden mellan huvudtråden ochWeb Worker
. Skicka data medpostMessage
och ta emot det medonmessage
.- Tråd-oberoende
Web Worker
fungerar helt oberoende av huvudtråden. Därför kan variabler och funktioner som definieras i huvudtråden inte nås. Nödvändiga data behöver skickas viapostMessage
. - Script-import
För att ladda externa skript i en
Web Worker
, användimportScripts()
.
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};
Alternativt kan du också använda import
enligt exemplet nedan.
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};
- Genom att ange
type: 'module'
i argumentet tillnew Worker
kan du behandla workern som en ES-modul och användaimport
-syntaxen.
Skillnader mellan Web Worker
och async
-funktioner
Web Worker
Funktioner
- Trådisolering
Web Worker
kör JavaScript-kod i en separat tråd. Detta möjliggör tung beräkning utan att blockera huvudtråden (UI-tråden). - Parallell bearbetning
Att använda
Web Worker
gör det möjligt för JavaScript-program att utföra parallell bearbetning i flera trådar. - Meddelandekommunikation
Web Worker
och huvudtråden delar inte data direkt, utan utbyter meddelanden viapostMessage
ochonmessage
. - Kan inte komma åt UI
Web Worker
kan inte komma åt DOM, så den kan inte direkt manipulera UI.
Användningsfall
- Den är lämplig för tunga beräkningsprocesser som bildbehandling, dataanalys och kryptering.
- Den kan användas när du inte vill blockera huvudtråden.
async
Funktioner
- Förenklar asynkron bearbetning
async
-funktionen är en syntax för att göra asynkron bearbetning mer läsbar och använderPromise
internt. - Enkel tråd
Alla
async
-funktioner körs på huvudtråden. Därför måste du hitta metoder för att undvika att blockera UI-tråden. - Optimalt för I/O-operationer Det passar för asynkrona uppgifter som nätverkskommunikation och filinläsning, men inte för tung beräkning.
Användningsfall
- Det lämpar sig för nätverkskommunikation som API-anrop.
- Det lämpar sig för filinläsning och -skrivning med hjälp av browser-API:er eller Node.js.
Huvudsakliga skillnader
Funktioner | Web Worker | async |
---|---|---|
Exekveringsmiljö | Separat tråd | Huvudtråd |
Syfte | Parallel bearbetning, avlastning av tunga beräkningar | Kortfattad beskrivning av asynkrona operationer |
DOM-åtkomst | Inte möjligt | Möjligt |
Kommunikationsmetod | Meddelandeöverföring (t.ex. postMessage ) |
Inte nödvändig (hanteras via direkta funktionsanrop eller await ) |
Användningsområden | Tidskrävande beräkningar, dataanalys | I/O-operationer, API-anrop |
När du ska använda varje
För CPU-intensiva uppgifter kan du använda Web Worker
för att minska belastningen på huvudtråden. Å andra sidan, för nätverkskommunikation eller I/O-operationer kan du förenkla din kod med hjälp av async
/await
.
Genom att kombinera båda på ett lämpligt sätt kan du uppnå effektiv asynkron bearbetning.
Exempel på användning av Web Worker
Exempel på avlastning av tunga beräkningar
Härnäst följer ett exempel på att avlasta tunga beräkningar.
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
- Den här koden är ett exempel på att använda en Web Worker för att separera och utföra tunga uppgifter, såsom beräkning av Fibonaccital, från huvudtråden.
Ett exempel på att specificera ett uppgiftsnamn
Härnäst följer ett exempel på att skicka och ta emot meddelanden genom att specificera ett uppgiftsnamn.
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 });
- Den här koden är ett exempel på att dirigera bearbetning baserat på
task
-namnet i meddelandet, därWeb Worker
returnerar beräkningsresultat eller fel till huvudtråden tillsammans med uppgiftsnamnet.
Anteckningar
När du använder Web Worker
, tänk på följande punkter.
- Kan inte komma åt DOM
Web Worker
kan inte manipulera UI:t eller komma åt DOM. DOM-manipulation behöver utföras i huvudtråden. - Kommunikationsöverhead
Det finns viss overhead vid datautbyte mellan huvudtråden och
Web Worker
. Detta kan påverka prestandan, särskilt vid frekvent utbyte av stora mängder data. - Same-Origin Policy
Web Worker
-skript lyder under same-origin policy. Skript kan inte laddas från olika domäner.
Att använda Web Worker
kan förbättra prestandan och responsiviteten i din applikation, men det är viktigt att använda det på rätt sätt med tanke på begränsningar som oförmågan att manipulera DOM:en.
Du kan följa med i artikeln ovan med hjälp av Visual Studio Code på vår YouTube-kanal. Vänligen kolla även in YouTube-kanalen.