JavaScript'te Web Workers

JavaScript'te Web Workers

Bu makale, JavaScript'teki Web Workers'ı açıklar.

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>

JavaScript'teki Web Worker

JavaScript'teki Web Worker, kodun ana iş parçacığından ayrı bir iş parçacığında çalışmasına olanak tanıyan bir mekanizmadır. Bu, yoğun hesaplamaların ve uzun süren işlemlerin eş zamansız şekilde gerçekleştirilmesini sağlar ve ana iş parçacığının bloke olmasını önler. Web Worker kullanarak, kullanıcı arayüzünün duyarlılığı artar ve uygulamanın performansı iyileşir.

Web Worker'ın temel kullanımı

Web Worker'ın temel kullanımına bir göz atalım.

Yeni bir Web Worker, bir JavaScript dosyası belirtilerek oluşturulur.

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};
  • Bu kod, ana iş parçacığından hesaplama isteği gönderip sonucu asenkron olarak almak için bir Web Worker kullanımının temel mekanizmasını gösterir. 10, Web Worker'a mesaj olarak gönderilir ve sonuç mesajı olarak 20 alınır. Ana iş parçacığı ile Web Worker, işleme sonuçlarını istemek ve almak için mesaj gönderip alarak iletişim kurar.

Temel işlevler

Web Worker aşağıdaki temel özellikleri sağlar.

  • postMessage ve onmessage Ana iş parçacığı ile Web Worker arasında mesaj göndermek ve almak için kullanılır. postMessage ile veri gönderin ve onmessage ile alın.
  • İş Parçacığı Bağımsızlığı Web Worker, ana iş parçacığından tamamen bağımsız olarak çalışır. Bu nedenle, ana iş parçacığında tanımlanan değişkenlere ve işlevlere erişilemez. Gerekli verilerin postMessage aracılığıyla geçirilmesi gerekir.
  • Betik İçe Aktarma Web Worker içinde harici betikleri yüklemek için importScripts() kullanılır.
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};

Alternatif olarak, aşağıda gösterildiği gibi import da kullanabilirsiniz.

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};
  • new Worker argümanında type: 'module' belirterek işçi dosyasını bir ES modülü olarak kullanabilir ve import sözdizimini kullanabilirsiniz.

Web Worker ile async fonksiyonlar arasındaki farklar

Web Worker

Özellikler
  • İş Parçacığı İzolasyonu Web Worker, JavaScript kodunu ayrı bir iş parçacığında çalıştırır. Bu, ana iş parçacığını (UI iş parçacığı) engellemeden ağır hesaplama işlemlerinin yapılmasına olanak tanır.
  • Eşzamanlı İşleme Web Worker kullanmak, JavaScript programlarının birden fazla iş parçacığında eşzamanlı işlem yapmasını sağlar.
  • Mesaj İletişimi Web Worker ile ana iş parçacığı verileri doğrudan paylaşmaz ve postMessage ile onmessage kullanarak mesaj alışverişi yapar.
  • UI'a Erişim Yoktur Web Worker, DOM'a erişemez; bu nedenle doğrudan kullanıcı arayüzünü değiştiremez.
Kullanım Alanları
  • Görsel işleme, veri analizi ve şifreleme gibi ağır hesaplama işlemleri için uygundur.
  • Ana iş parçacığını engellemek istemediğiniz durumlarda kullanılabilir.

async

Özellikler
  • Asenkron İşlemleri Basitleştirme async fonksiyonu, asenkron işlemleri daha okunaklı hale getirmek için kullanılan bir sözdizimidir ve dahili olarak Promise kullanır.
  • Tek İş Parçacığı Tüm async fonksiyonlar ana iş parçacığında çalışır. Bu nedenle, UI iş parçacığını engellemekten kaçınmak için yöntemler geliştirmeniz gerekir.
  • G/Ç İşlemleri için Uygundur Ağ iletişimi ve dosya okuma gibi asenkron işlemler için uygundur; ancak ağır hesaplamalar için uygun değildir.
Kullanım Alanları
  • API çağrıları gibi ağ iletişimi için uygundur.
  • Tarayıcı API'leri veya Node.js kullanarak dosya okuma ve yazma işlemleri için uygundur.

Temel Farklılıklar

Özellikler Web Worker async
Çalışma Ortamı Ayrı iş parçacığı Ana iş parçacığı
Amaç Paralel işlem, ağır hesaplamaların delege edilmesi Asenkron işlemlerin özlü açıklaması
DOM Erişimi Mümkün değil Mümkün
İletişim Yöntemi Mesaj iletimi (örn. postMessage) Gerekli değil (doğrudan fonksiyon çağrıları veya await ile ele alınır)
Kullanım Durumları Zaman alıcı hesaplamalar, veri analizi G/Ç işlemleri, API çağrıları

Hangisini Ne Zaman Kullanmalı

CPU yoğunluklu görevler için, ana iş parçacığındaki yükü azaltmak için Web Worker kullanabilirsiniz. Öte yandan, ağ iletişimi veya G/Ç işlemleri için async/await kullanarak kodunuzu basitleştirebilirsiniz.

Her ikisini uygun şekilde birleştirerek verimli bir asenkron işlem elde edebilirsiniz.

Web Worker Kullanım Örnekleri

Yoğun Hesaplama İş Yükünü Hafifletme Örneği

Sonraki, ağır hesaplamaların ana iş parçacığından alınmasına bir örnektir.

 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
  • Bu kod, ana iş parçacığından Fibonacci dizisi hesaplamaları gibi ağır görevleri ayırmak ve yürütmek için bir Web Worker kullanmaya bir örnektir.

Bir görev adının belirtilmesine örnek

Sonraki, bir görev adı belirterek mesaj gönderip alma örneğidir.

 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 });
  • Web Worker'ın hesaplama sonuçlarını veya hataları görev adı ile birlikte ana iş parçacığına döndürmesiyle, mesajdaki task adına göre işleme yönlendirme örneğidir.

Notlar

Web Worker kullanırken aşağıdaki noktalara dikkat edin.

  • DOM'a Erişim Yoktur Web Worker, kullanıcı arayüzünü değiştiremez veya DOM'a erişemez. DOM manipülasyonunun ana iş parçacığında gerçekleştirilmesi gerekir.
  • İletişim Yükü Ana iş parçacığı ile Web Worker arasında veri alışverişinde bir miktar ek yük oluşur. Bu, özellikle büyük miktarda verinin sıkça değiş tokuş edildiği durumlarda performansı etkileyebilir.
  • Aynı Kaynak Politikası Web Worker betikleri aynı kaynak politikasına tabidir. Betikler farklı etki alanlarından yüklenemez.

Web Worker kullanmak, uygulamanızın performansını ve duyarlılığını artırabilir, ancak DOM manipülasyonu yapamama gibi kısıtlamaları göz önünde bulundurarak uygun bir şekilde kullanmak önemlidir.

Yukarıdaki makaleyi, YouTube kanalımızda Visual Studio Code'u kullanarak takip edebilirsiniz. Lütfen YouTube kanalını da kontrol edin.

YouTube Video