Webarbejdere i JavaScript

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 &amp; 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 sender 10 som en besked til Web Worker og modtager 20 som resultatbesked. Hovedtråden og Web 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 og onmessage Bruges til at sende og modtage beskeder mellem hovedtråden og Web Worker. Send data med postMessage og modtag dem med onmessage.
  • 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 via postMessage.
  • Scriptimport For at indlæse eksterne scripts i en Web Worker skal du bruge importScripts().
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 til new Worker kan du behandle worker'en som et ES-modul og bruge import-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 af postMessage og onmessage.
  • 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 bruger Promise 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, hvor Web 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.

YouTube Video