Web Workers๋Š” JavaScript ์ฝ”๋“œ๋ฅผ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” Web API์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฌด๊ฑฐ์šด ์—ฐ์‚ฐ์„ ๋ณ„๋„ ์Šค๋ ˆ๋“œ์—์„œ ์ฒ˜๋ฆฌํ•˜์—ฌ, ๋ฉ”์ธ ์Šค๋ ˆ๋“œ(UI ์Šค๋ ˆ๋“œ)๊ฐ€ ์ฐจ๋‹จ๋˜๊ฑฐ๋‚˜ ๋А๋ ค์ง€์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ”์ธ ์Šค๋ ˆ๋“œ์™€ ์›Œ์ปค ์Šค๋ ˆ๋“œ๋Š” ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ(message passing) ์‹œ์Šคํ…œ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ๋Š” ๊ณต์œ ๋˜์ง€ ์•Š๊ณ  ๋ณต์‚ฌ๋˜์–ด ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” race condition์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ๊ฐœ๋…์ด ํ•„์š”ํ•œ ์ด์œ 

  • UI ๋ธ”๋กœํ‚น ๋ฐฉ์ง€: ๋ณต์žกํ•œ ๊ณ„์‚ฐ, ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ, ์ด๋ฏธ์ง€/๋น„๋””์˜ค ์ธ์ฝ”๋”ฉ ๋“ฑ ๋ฌด๊ฑฐ์šด ์ž‘์—…์„ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•˜๋ฉด UI๊ฐ€ ๋ฉˆ์ถ”๊ฑฐ๋‚˜ ๋ฒ„๋ฒ…๊ฑฐ๋ฆฝ๋‹ˆ๋‹ค. Web Workers๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด UI๊ฐ€ ๋Š๊น€ ์—†์ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค
  • ๋ฉ€ํ‹ฐ ์ฝ”์–ด ํ™œ์šฉ: ํ˜„๋Œ€ CPU๋Š” ์—ฌ๋Ÿฌ ์ฝ”์–ด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, JavaScript๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ์ž…๋‹ˆ๋‹ค. Web Workers๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ์ฝ”์–ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค
  • ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ๊ฐœ์„ : ๊ธด ์ž‘์—… ์ค‘์—๋„ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ์Šคํฌ๋กคํ•˜๊ฑฐ๋‚˜ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•  ์ˆ˜ ์žˆ์–ด, ๋ฐ˜์‘์„ฑ์ด ๋›ฐ์–ด๋‚œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

AS-IS: ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ๋ฌด๊ฑฐ์šด ์ž‘์—… ์‹คํ–‰

// ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฐจ๋‹จ๋จ
function calculatePrimes(max) {
  const primes = [];
  for (let i = 2; i < max; i++) {
    let isPrime = true;
    for (let j = 2; j < i; j++) {
      if (i % j === 0) {
        isPrime = false;
        break;
      }
    }
    if (isPrime) primes.push(i);
  }
  return primes;
}
 
// UI๊ฐ€ ๋ฉˆ์ถค (๊ณ„์‚ฐ์ด ๋๋‚  ๋•Œ๊นŒ์ง€)
const result = calculatePrimes(100000);
console.log(result);
sequenceDiagram
    autonumber
    participant User
    participant MainThread as Main Thread<br/>(UI + ๊ณ„์‚ฐ)

    User->>MainThread: ๋ฒ„ํŠผ ํด๋ฆญ (๋ฌด๊ฑฐ์šด ๊ณ„์‚ฐ ์‹œ์ž‘)
    Note over MainThread: ๊ณ„์‚ฐ ์ค‘...<br/>UI ๋ธ”๋กœํ‚น!
    User->>MainThread: ์Šคํฌ๋กค ์‹œ๋„
    Note over User: โŒ UI ๋ฐ˜์‘ ์—†์Œ
    Note over MainThread: ๊ณ„์‚ฐ ์™„๋ฃŒ
    MainThread->>User: ๊ฒฐ๊ณผ ํ‘œ์‹œ

TO-BE: Web Workers๋กœ ๋ถ„๋ฆฌ

// main.js - ๋ฉ”์ธ ์Šค๋ ˆ๋“œ
const worker = new Worker('worker.js');
 
worker.postMessage({ max: 100000 });
 
worker.onmessage = function(event) {
  console.log('๊ณ„์‚ฐ ์™„๋ฃŒ:', event.data);
};
 
// UI๋Š” ๊ณ„์† ๋ฐ˜์‘ํ•จ
// worker.js - ์›Œ์ปค ์Šค๋ ˆ๋“œ
onmessage = function(event) {
  const { max } = event.data;
 
  const primes = calculatePrimes(max);
 
  postMessage(primes);
};
 
function calculatePrimes(max) {
  const primes = [];
  for (let i = 2; i < max; i++) {
    let isPrime = true;
    for (let j = 2; j < i; j++) {
      if (i % j === 0) {
        isPrime = false;
        break;
      }
    }
    if (isPrime) primes.push(i);
  }
  return primes;
}
sequenceDiagram
    autonumber
    participant User
    participant MainThread as Main Thread<br/>(UI)
    participant Worker as Worker Thread<br/>(๊ณ„์‚ฐ)

    User->>MainThread: ๋ฒ„ํŠผ ํด๋ฆญ
    MainThread->>Worker: postMessage({ max: 100000 })
    Note over Worker: ๊ณ„์‚ฐ ์ค‘...
    User->>MainThread: ์Šคํฌ๋กค ์‹œ๋„
    Note over User: โœ… UI ์ •์ƒ ๋ฐ˜์‘
    Note over Worker: ๊ณ„์‚ฐ ์™„๋ฃŒ
    Worker->>MainThread: postMessage(result)
    MainThread->>User: ๊ฒฐ๊ณผ ํ‘œ์‹œ

Web Workers์˜ ์ข…๋ฅ˜

์ข…๋ฅ˜์„ค๋ช…์‚ฌ์šฉ ์‚ฌ๋ก€
Dedicated Workers๋‹จ์ผ ์Šคํฌ๋ฆฝํŠธ์—์„œ๋งŒ ์‚ฌ์šฉ. ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ํ˜•ํƒœํŠน์ • ํŽ˜์ด์ง€์˜ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…
Shared Workers์—ฌ๋Ÿฌ ์ฐฝ, ํƒญ, iframe์—์„œ ๊ณต์œ  ๊ฐ€๋Šฅ. ๊ฐ™์€ ๋„๋ฉ”์ธ ํ•„์š”์—ฌ๋Ÿฌ ํƒญ ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ณต์œ , ์ค‘์•™ ์ง‘์ค‘์‹ ์ฒ˜๋ฆฌ
Service Workers์•ฑ-๋ธŒ๋ผ์šฐ์ €-๋„คํŠธ์›Œํฌ ์‚ฌ์ด์˜ ํ”„๋ก์‹œ ์—ญํ• . ์˜คํ”„๋ผ์ธ ์ง€์›, ํ‘ธ์‹œ ์•Œ๋ฆผPWA, ์˜คํ”„๋ผ์ธ ๊ฒฝํ—˜, ๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋™๊ธฐํ™”

Dedicated Worker ์‚ฌ์šฉ๋ฒ•

Worker ์ƒ์„ฑ ๋ฐ ๋ฉ”์‹œ์ง€ ์ „์†ก

๋ฉ”์ธ ์Šค๋ ˆ๋“œ (main.js)

// 1. Worker ์ƒ์„ฑ
const worker = new Worker('worker.js');
 
// 2. ์›Œ์ปค์—๊ฒŒ ๋ฉ”์‹œ์ง€ ์ „์†ก
worker.postMessage({
  command: 'start',
  data: [1, 2, 3, 4, 5]
});
 
// 3. ์›Œ์ปค๋กœ๋ถ€ํ„ฐ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹ 
worker.onmessage = function(event) {
  console.log('์›Œ์ปค ๊ฒฐ๊ณผ:', event.data);
  // event.data = { status: 'complete', result: 15 }
};
 
// 4. ์—๋Ÿฌ ์ฒ˜๋ฆฌ
worker.onerror = function(error) {
  console.error('์›Œ์ปค ์—๋Ÿฌ:', error.message);
  console.error('ํŒŒ์ผ:', error.filename);
  console.error('๋ผ์ธ:', error.lineno);
};
 
// 5. ์›Œ์ปค ์ข…๋ฃŒ
worker.terminate();

์›Œ์ปค ์Šค๋ ˆ๋“œ (worker.js)

// ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ๋ฉ”์‹œ์ง€ ์ˆ˜์‹ 
onmessage = function(event) {
  const { command, data } = event.data;
 
  if (command === 'start') {
    // ๋ฌด๊ฑฐ์šด ์ž‘์—… ์ˆ˜ํ–‰
    const sum = data.reduce((acc, val) => acc + val, 0);
 
    // ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋กœ ๊ฒฐ๊ณผ ์ „์†ก
    postMessage({
      status: 'complete',
      result: sum
    });
  }
};
 
// ์›Œ์ปค ์ž์ฒด ์ข…๋ฃŒ
// close();

addEventListener๋ฅผ ์‚ฌ์šฉํ•œ ๋ฐฉ๋ฒ•

// ๋ฉ”์ธ ์Šค๋ ˆ๋“œ
const worker = new Worker('worker.js');
 
worker.addEventListener('message', function(event) {
  console.log('๋ฉ”์‹œ์ง€ ์ˆ˜์‹ :', event.data);
});
 
worker.addEventListener('error', function(error) {
  console.error('์—๋Ÿฌ ๋ฐœ์ƒ:', error);
});
 
worker.postMessage('Hello Worker');
// ์›Œ์ปค ์Šค๋ ˆ๋“œ
addEventListener('message', function(event) {
  console.log('๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ:', event.data);
  postMessage('Hello Main Thread');
});

Worker์˜ ์ฃผ์š” ํŠน์ง• 4๊ฐ€์ง€

1. ๋ฉ”์‹œ์ง€ ํŒจ์‹ฑ ์‹œ์Šคํ…œ

๋ฉ”์ธ ์Šค๋ ˆ๋“œ์™€ ์›Œ์ปค ์Šค๋ ˆ๋“œ๋Š” ์ง์ ‘์ ์ธ ๋ฐ์ดํ„ฐ ๊ณต์œ  ์—†์ด postMessage()์™€ onmessage๋ฅผ ํ†ตํ•ด ํ†ต์‹ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋Š” ๋ณต์‚ฌ๋˜์–ด ์ „๋‹ฌ๋˜๋ฏ€๋กœ race condition์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

// ๋ฉ”์ธ ์Šค๋ ˆ๋“œ
const data = { numbers: [1, 2, 3] };
worker.postMessage(data);
 
// ์›๋ณธ ์ˆ˜์ •ํ•ด๋„ ์›Œ์ปค์—๊ฒŒ ์˜ํ–ฅ ์—†์Œ
data.numbers.push(4);
// ์›Œ์ปค ์Šค๋ ˆ๋“œ
onmessage = function(event) {
  const receivedData = event.data;
  // receivedData.numbers = [1, 2, 3] (๋ณต์‚ฌ๋ณธ)
 
  receivedData.numbers.push(10);
  postMessage(receivedData);
};

๋ฉ”์‹œ์ง€ ํ๋ฆ„:

Main Thread              Worker Thread
    |                        |
    |--- postMessage() ----->|
    |                    onmessage
    |                  [Process]
    |<-- postMessage() -------|
  onmessage                   |

2. Worker Scope์™€ ์ œํ•œ ์‚ฌํ•ญ

Worker๋Š” ๋ณ„๋„์˜ ์ „์—ญ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง€๋ฉฐ, ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์˜ ์ผ๋ถ€ API์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

โŒ Worker์—์„œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฒƒ

  • DOM ์กฐ์ž‘: document, window, parent ์ ‘๊ทผ ๋ถˆ๊ฐ€
  • DOM API: alert(), confirm(), prompt()
  • ์ผ๋ถ€ Window ๋ฉ”์„œ๋“œ/์†์„ฑ
// โŒ Worker์—์„œ ๋ถˆ๊ฐ€๋Šฅ
onmessage = function(event) {
  document.getElementById('result').textContent = 'Done'; // ์—๋Ÿฌ!
  alert('Finished'); // ์—๋Ÿฌ!
};

โœ… Worker์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ฒƒ

  • ํ‘œ์ค€ JavaScript: String, Array, Object, JSON, Math
  • ํƒ€์ด๋จธ: setTimeout(), setInterval()
  • ๋„คํŠธ์›Œํฌ ์š”์ฒญ: fetch(), XMLHttpRequest
  • WebSockets
  • importScripts(): ์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ ๋กœ๋”ฉ
// โœ… Worker์—์„œ ๊ฐ€๋Šฅ
onmessage = async function(event) {
  // fetch ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
 
  // JSON ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  const processed = JSON.stringify(data);
 
  postMessage(processed);
};

Worker Global Scope ์ข…๋ฅ˜

Scope์„ค๋ช…
DedicatedWorkerGlobalScopeDedicated Worker์˜ ์ „์—ญ ์Šค์ฝ”ํ”„
SharedWorkerGlobalScopeShared Worker์˜ ์ „์—ญ ์Šค์ฝ”ํ”„
ServiceWorkerGlobalScopeService Worker์˜ ์ „์—ญ ์Šค์ฝ”ํ”„
WorkerGlobalScope๋ชจ๋“  ์›Œ์ปค๊ฐ€ ์ƒ์†ํ•˜๋Š” ๊ธฐ๋ณธ ์Šค์ฝ”ํ”„

3. importScripts()๋กœ ์™ธ๋ถ€ ์Šคํฌ๋ฆฝํŠธ ๋กœ๋”ฉ

Worker ๋‚ด๋ถ€์—์„œ ์—ฌ๋Ÿฌ JavaScript ํŒŒ์ผ์„ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// worker.js
importScripts('utils.js', 'math-helpers.js', 'data-processor.js');
 
// ์ด์ œ ๋กœ๋“œ๋œ ํŒŒ์ผ์˜ ํ•จ์ˆ˜๋“ค์„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
onmessage = function(event) {
  const result = calculateSum(event.data); // utils.js์—์„œ ์ •์˜
  postMessage(result);
};

ํŠน์ง•:

  • ๋™๊ธฐ์ ์œผ๋กœ ๋กœ๋“œ๋จ (์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰)
  • ์—ฌ๋Ÿฌ ํŒŒ์ผ์„ ํ•œ ๋ฒˆ์— ๋กœ๋“œ ๊ฐ€๋Šฅ
  • ๋กœ๋“œ ์‹คํŒจ ์‹œ ์›Œ์ปค๊ฐ€ ์ข…๋ฃŒ๋จ

4. ์›Œ์ปค์—์„œ ์›Œ์ปค ์ƒ์„ฑ ๊ฐ€๋Šฅ

Worker๋Š” ์ƒˆ๋กœ์šด ์›Œ์ปค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ, **๊ฐ™์€ origin(์ถœ์ฒ˜)**์— ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// worker.js
onmessage = function(event) {
  // ์„œ๋ธŒ ์›Œ์ปค ์ƒ์„ฑ
  const subWorker = new Worker('sub-worker.js');
 
  subWorker.postMessage(event.data);
 
  subWorker.onmessage = function(subEvent) {
    // ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋กœ ๊ฒฐ๊ณผ ์ „๋‹ฌ
    postMessage(subEvent.data);
  };
};

์‹ค์ œ ์‚ฌ์šฉ ์‚ฌ๋ก€

1. ์ด๋ฏธ์ง€ ์ฒ˜๋ฆฌ

// main.js
const worker = new Worker('image-processor.js');
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
 
// ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
 
worker.postMessage({
  command: 'process',
  imageData: imageData
});
 
worker.onmessage = function(event) {
  // ์ฒ˜๋ฆฌ๋œ ์ด๋ฏธ์ง€ ๋ฐ์ดํ„ฐ๋กœ ์บ”๋ฒ„์Šค ์—…๋ฐ์ดํŠธ
  ctx.putImageData(event.data.imageData, 0, 0);
};
// image-processor.js
onmessage = function(event) {
  const { command, imageData } = event.data;
 
  if (command === 'process') {
    const data = imageData.data;
 
    // ๊ทธ๋ ˆ์ด์Šค์ผ€์ผ ๋ณ€ํ™˜ (๋ฌด๊ฑฐ์šด ์ž‘์—…)
    for (let i = 0; i < data.length; i += 4) {
      const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;
      data[i] = avg;     // Red
      data[i + 1] = avg; // Green
      data[i + 2] = avg; // Blue
    }
 
    postMessage({ imageData: imageData });
  }
};

2. ๋Œ€์šฉ๋Ÿ‰ JSON ํŒŒ์‹ฑ

// main.js
const worker = new Worker('json-parser.js');
 
fetch('large-data.json')
  .then(response => response.text())
  .then(jsonString => {
    worker.postMessage({ json: jsonString });
  });
 
worker.onmessage = function(event) {
  const parsedData = event.data;
  console.log('ํŒŒ์‹ฑ ์™„๋ฃŒ:', parsedData);
  updateUI(parsedData);
};
// json-parser.js
onmessage = function(event) {
  const { json } = event.data;
 
  // ๋Œ€์šฉ๋Ÿ‰ JSON ํŒŒ์‹ฑ (๋ฉ”์ธ ์Šค๋ ˆ๋“œ ๋ธ”๋กœํ‚น ์—†์Œ)
  const parsed = JSON.parse(json);
 
  // ์ถ”๊ฐ€ ์ฒ˜๋ฆฌ
  const processed = parsed.items.map(item => ({
    id: item.id,
    name: item.name,
    processed: true
  }));
 
  postMessage(processed);
};

3. ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ๋ถ„์„

// main.js
const worker = new Worker('analytics.js');
 
// ์ฃผ๊ธฐ์ ์œผ๋กœ ๋ฐ์ดํ„ฐ ์ „์†ก
setInterval(() => {
  const sensorData = readSensorData();
  worker.postMessage({ data: sensorData });
}, 100);
 
worker.onmessage = function(event) {
  const { analysis } = event.data;
  updateDashboard(analysis);
};
// analytics.js
let dataBuffer = [];
 
onmessage = function(event) {
  dataBuffer.push(event.data.data);
 
  if (dataBuffer.length >= 10) {
    // ํ†ต๊ณ„ ๋ถ„์„
    const avg = dataBuffer.reduce((a, b) => a + b, 0) / dataBuffer.length;
    const max = Math.max(...dataBuffer);
    const min = Math.min(...dataBuffer);
 
    postMessage({
      analysis: { avg, max, min }
    });
 
    dataBuffer = [];
  }
};

4. ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™”

// main.js
const worker = new Worker('crypto-worker.js');
 
worker.postMessage({
  command: 'encrypt',
  text: 'Sensitive data',
  key: 'secret-key'
});
 
worker.onmessage = function(event) {
  console.log('์•”ํ˜ธํ™” ์™„๋ฃŒ:', event.data.encrypted);
};
// crypto-worker.js
importScripts('crypto-lib.js'); // ์™ธ๋ถ€ ์•”ํ˜ธํ™” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
 
onmessage = function(event) {
  const { command, text, key } = event.data;
 
  if (command === 'encrypt') {
    const encrypted = performEncryption(text, key);
    postMessage({ encrypted: encrypted });
  }
};

์—๋Ÿฌ ์ฒ˜๋ฆฌ ๋ฐ ๋””๋ฒ„๊น…

์—๋Ÿฌ ํ•ธ๋“ค๋Ÿฌ

// ๋ฉ”์ธ ์Šค๋ ˆ๋“œ
worker.onerror = function(error) {
  console.error('์›Œ์ปค ์—๋Ÿฌ ๋ฐœ์ƒ');
  console.error('๋ฉ”์‹œ์ง€:', error.message);
  console.error('ํŒŒ์ผ:', error.filename);
  console.error('๋ผ์ธ ๋ฒˆํ˜ธ:', error.lineno);
 
  // ์—๋Ÿฌ ๋ณต๊ตฌ ๋กœ์ง
  worker.terminate();
  worker = new Worker('worker.js'); // ์žฌ์‹œ์ž‘
};

Worker ์ข…๋ฃŒ

// ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์ข…๋ฃŒ
worker.terminate();
console.log('์›Œ์ปค ์ข…๋ฃŒ๋จ');
 
// ์›Œ์ปค๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ๋” ์ด์ƒ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ›์„ ์ˆ˜ ์—†์Œ
// ์›Œ์ปค ์Šค๋ ˆ๋“œ ๋‚ด๋ถ€์—์„œ ์ž์ฒด ์ข…๋ฃŒ
onmessage = function(event) {
  if (event.data.command === 'shutdown') {
    close(); // ์›Œ์ปค ์ž์ฒด ์ข…๋ฃŒ
  }
};

์ฐธ๊ณ  ๋ฌธ์„œ