Web Worker in JavaScript

Web Worker in JavaScript

Dieser Artikel erklärt 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 &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 in JavaScript

Web Worker in JavaScript ist ein Mechanismus, der es ermöglicht, Code in einem separaten Thread neben dem Hauptthread auszuführen. Dies ermöglicht es, aufwendige Berechnungen und langfristige Operationen asynchron auszuführen, wodurch der Hauptthread nicht blockiert wird. Durch die Verwendung von Web Worker verbessert sich die Reaktionsfähigkeit der Benutzeroberfläche, und die Leistung der Anwendung wird gesteigert.

Die grundlegende Verwendung von Web Worker

Sehen wir uns die grundlegende Verwendung von Web Worker an.

Ein neuer Web Worker wird erstellt, indem eine JavaScript-Datei angegeben wird.

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};
  • Dieser Code demonstriert den grundlegenden Mechanismus, einen Web Worker zu verwenden, um Berechnungen vom Hauptthread anzufordern und das Ergebnis asynchron zu empfangen. Er sendet 10 als Nachricht an den Web Worker und erhält 20 als Ergebnisnachricht. Der Hauptthread und der Web Worker kommunizieren, indem sie Nachrichten senden und empfangen, um Verarbeitungsergebnisse anzufordern und zu empfangen.

Grundlegende Funktionen

Web Worker bietet die folgenden grundlegenden Funktionen:.

  • postMessage und onmessage Wird verwendet, um Nachrichten zwischen dem Hauptthread und dem Web Worker zu senden und zu empfangen. Daten mit postMessage senden und mit onmessage empfangen.
  • Thread-Unabhängigkeit Web Worker arbeitet völlig unabhängig vom Hauptthread. Daher können Variablen und Funktionen, die im Hauptthread definiert sind, nicht zugegriffen werden. Notwendige Daten müssen über postMessage übergeben werden.
  • Skriptimport Um externe Skripte innerhalb eines Web Worker zu laden, verwende 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};

Alternativ kann auch import wie unten gezeigt verwendet werden.

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};
  • Indem man type: 'module' im Argument von new Worker angibt, kann der Worker als ES-Modul behandelt werden und die import-Syntax verwenden.

Unterschiede zwischen Web Worker und async-Funktionen

Web Worker

Eigenschaften
  • Thread-Isolation Web Worker führt JavaScript-Code in einem separaten Thread aus. Dies ermöglicht es, aufwendige Berechnungen durchzuführen, ohne den Hauptthread (UI-Thread) zu blockieren.
  • Parallele Verarbeitung Mit Web Worker können JavaScript-Programme parallele Verarbeitung in mehreren Threads durchführen.
  • Nachrichtenkommunikation Web Worker und Hauptthread teilen keine Daten direkt und tauschen Nachrichten mit postMessage und onmessage aus.
  • Kein Zugriff auf die UI Web Worker kann nicht auf das DOM zugreifen und kann daher die UI nicht direkt manipulieren.
Anwendungsfälle
  • Es eignet sich für aufwendige Berechnungsprozesse wie Bildverarbeitung, Datenanalyse und Verschlüsselung.
  • Es kann verwendet werden, wenn der Hauptthread nicht blockiert werden soll.

async

Eigenschaften
  • Vereinfachung der asynchronen Verarbeitung Die async-Funktion ist eine Syntax, um asynchrone Verarbeitung lesbarer zu machen und verwendet intern Promise.
  • Einzelner Thread Alle async-Funktionen laufen im Hauptthread. Deshalb muss man Wege finden, um eine Blockierung des UI-Threads zu vermeiden.
  • Optimal für I/O-Operationen Sie eignet sich für asynchrone Aufgaben wie Netzwerkkommunikation und Dateilesen, aber nicht für rechenintensive Aufgaben.
Anwendungsfälle
  • Sie eignet sich für Netzwerkkommunikation, wie z.B. API-Aufrufe.
  • Sie eignet sich zum Lesen und Schreiben von Dateien mit Hilfe von Browser-APIs oder Node.js.

Hauptunterschiede

Eigenschaften Web Worker async
Ausführungsumgebung Separater Thread Haupt-Thread
Zweck Parallele Verarbeitung, Entlastung schwerer Berechnungen Prägnante Beschreibung asynchroner Vorgänge
DOM-Zugriff Nicht möglich Möglich
Kommunikationsmethode Nachrichtenübermittlung (z.B. postMessage) Nicht erforderlich (über direkte Funktionsaufrufe oder await behandelt)
Anwendungsfälle Zeitaufwendige Berechnungen, Datenanalyse I/O-Operationen, API-Aufrufe

Wann welche verwendet werden sollte

Für CPU-intensive Aufgaben können Sie Web Worker verwenden, um die Belastung des Haupt-Threads zu reduzieren. Für Netzwerkommunikation oder I/O-Operationen können Sie andererseits Ihren Code mit async/await vereinfachen.

Durch die angemessene Kombination beider Methoden können Sie eine effiziente asynchrone Verarbeitung erreichen.

Beispiele für die Verwendung von Web Worker

Beispiel für das Auslagern von aufwendigen Berechnungen

Als Nächstes folgt ein Beispiel für das Auslagern von rechenintensiven Aufgaben.

 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
  • Dieser Code ist ein Beispiel dafür, wie ein Web Worker verwendet wird, um schwere Aufgaben wie die Berechnung der Fibonacci-Folge vom Haupt-Thread zu trennen und auszuführen.

Ein Beispiel für die Angabe eines Aufgaben-Namens

Als Nächstes folgt ein Beispiel für das Senden und Empfangen von Nachrichten unter Angabe eines Aufgaben-Namens.

 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 });
  • Dieser Code ist ein Beispiel dafür, die Verarbeitung basierend auf dem task-Namen in der Nachricht zu steuern, wobei der Web Worker die Berechnungsergebnisse oder Fehler zusammen mit dem Aufgaben-Namen an den Haupt-Thread zurückgibt.

Notizen

Beim Einsatz von Web Worker sollten die folgenden Punkte beachtet werden:.

  • Kein Zugriff auf das DOM Web Worker kann die Benutzeroberfläche nicht manipulieren oder auf das DOM zugreifen. Die DOM-Manipulation muss im Hauptthread erfolgen.
  • Kommunikationsaufwand Beim Datenaustausch zwischen Hauptthread und Web Worker entsteht ein gewisser Overhead. Dies kann die Leistung beeinträchtigen, insbesondere wenn häufig große Datenmengen ausgetauscht werden.
  • Same-Origin-Policy Web Worker-Skripte unterliegen der Same-Origin-Policy. Skripte können nicht von verschiedenen Domains geladen werden.

Die Verwendung von Web Worker kann die Leistung und Reaktionsfähigkeit Ihrer Anwendung verbessern. Es ist jedoch wichtig, diese in Anbetracht von Einschränkungen wie der Unfähigkeit, das DOM zu manipulieren, angemessen einzusetzen.

Sie können den obigen Artikel mit Visual Studio Code auf unserem YouTube-Kanal verfolgen. Bitte schauen Sie sich auch den YouTube-Kanal an.

YouTube Video