Webarbejdere i JavaScript
Denne artikel forklarer webarbejdere 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 er en mekanisme, der gør det muligt at køre kode i en separat tråd fra hovedtråden. Dette gør det muligt at udføre tunge beregninger og langvarige operationer asynkront, hvilket forhindrer hovedtråden i at blive blokeret. Ved at bruge Web Worker
forbedres brugergrænsefladens reaktionsevne, og applikationens ydeevne øges.
Grundlæggende brug af Web Worker
Lad os se på den grundlæggende anvendelse af Web Worker
.
En ny Web Worker
oprettes ved at angive 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};
- Denne kode demonstrerer den grundlæggende mekanisme til at bruge en
Web Worker
til at anmode om beregning fra hovedtråden og modtage resultatet asynkront. Den sender10
som en besked tilWeb Worker
og modtager20
som resultatbesked. Hovedtråden ogWeb Worker
kommunikerer ved at sende og modtage beskeder for at anmode om og modtage behandlingsresultater.
Grundlæggende funktioner
Web Worker
tilbyder følgende grundlæggende funktioner.
postMessage
ogonmessage
Bruges til at sende og modtage beskeder mellem hovedtråden ogWeb Worker
. Send data medpostMessage
og modtag dem medonmessage
.- Tråduafhængighed
Web Worker
fungerer helt uafhængigt af hovedtråden. Derfor kan variabler og funktioner defineret i hovedtråden ikke tilgås. Nødvendige data skal overføres viapostMessage
. - Scriptimport
For at indlæse eksterne scripts i en
Web Worker
skal du brugeimportScripts()
.
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 også bruge import
som vist nedenfor.
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};
- Ved at angive
type: 'module'
i argumentet tilnew Worker
kan du behandle worker'en som et ES-modul og brugeimport
-syntaksen.
Forskelle mellem Web Worker
og async
-funktioner
Web Worker
Egenskaber
- Trådisolation
Web Worker
udfører JavaScript-kode i en separat tråd. Dette gør det muligt at udføre tunge beregninger uden at blokere hovedtråden (UI-tråden). - Samtidig behandling
Ved at bruge
Web Worker
kan JavaScript-programmer udføre samtidig behandling i flere tråde. - Beskedkommunikation
Web Worker
og hovedtråden deler ikke data direkte og udveksler beskeder ved hjælp afpostMessage
ogonmessage
. - Kan ikke tilgå UI
Web Worker
har ikke adgang til DOM'et og kan derfor ikke manipulere UI'et direkte.
Anvendelsestilfælde
- Den er velegnet til tunge beregningsprocesser som billedbehandling, dataanalyse og kryptering.
- Den kan bruges, når du ikke ønsker at blokere hovedtråden.
async
Egenskaber
- Forenkling af asynkron behandling
async
-funktionen er en syntaks, der gør asynkron behandling mere læsbar og brugerPromise
internt. - Enkelt tråd
Alle
async
-funktioner kører på hovedtråden. Derfor skal du finde metoder til at undgå at blokere UI-tråden. - Optimal til I/O-operationer Det er velegnet til asynkrone opgaver såsom netværkskommunikation og filindlæsning, men ikke til tunge beregninger.
Anvendelsestilfælde
- Det er egnet til netværkskommunikation som f.eks. API-kald.
- Det er egnet til filindlæsning og -skrivning ved brug af browser-API'er eller Node.js.
Væsentlige Forskelle
Egenskaber | Web Worker | async |
---|---|---|
Udførelsesmiljø | Separat tråd | Hovedtråd |
Formål | Parallel behandling, aflaste tunge beregninger | Kortfattet beskrivelse af asynkrone operationer |
DOM-adgang | Ikke muligt | Muligt |
Kommunikationsmetode | Meddelelsesoverførsel (f.eks. postMessage ) |
Ikke nødvendigt (håndteres via direkte funktionskald eller await ) |
Anvendelsestilfælde | Tidskrævende beregninger, dataanalyse | I/O-operationer, API-kald |
Hvornår Skal Hver Bruges
Til CPU-intensive opgaver kan du bruge Web Worker
for at reducere belastningen på hovedtråden. Til gengæld kan du for netværkskommunikation eller I/O-operationer forenkle din kode ved hjælp af async
/await
.
Ved at kombinere begge dele på passende vis kan du opnå effektiv asynkron behandling.
Eksempler på brug af Web Worker
Eksempel på aflastning af tunge beregninger
Næste er et eksempel på at overføre tunge beregninger.
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
- Denne kode er et eksempel på at bruge en Web Worker til at adskille og udføre tunge opgaver som beregning af Fibonacci-sekvenser væk fra hovedtråden.
Et eksempel på at angive et opgavenavn
Næste er et eksempel på at sende og modtage beskeder ved at angive et opgavenavn.
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 });
- Denne kode er et eksempel på at styre behandling baseret på
task
-navnet i beskeden, hvorWeb Worker
returnerer beregningsresultater eller fejl til hovedtråden sammen med opgavenavnet.
Noter
Når du bruger Web Worker
, skal du være opmærksom på følgende punkter.
- Kan ikke tilgå DOM
Web Worker
kan ikke manipulere UI'et eller få adgang til DOM'et. DOM-manipulation skal udføres i hovedtråden. - Kommunikationsomkostninger
Der er en vis omkostning ved udveksling af data mellem hovedtråden og
Web Worker
. Dette kan påvirke ydeevnen, især når der ofte udveksles store mængder data. - Samme-origin politik
Web Worker
-scripts er underlagt same-origin politikken. Scripts kan ikke indlæses fra forskellige domæner.
Brug af Web Worker
kan forbedre ydeevnen og reaktionshastigheden i din applikation, men det er vigtigt at bruge det på passende vis under hensyn til begrænsninger som manglende mulighed for at manipulere DOM'en.
Du kan følge med i ovenstående artikel ved hjælp af Visual Studio Code på vores YouTube-kanal. Husk også at tjekke YouTube-kanalen.