HTML5 - 웹 워커(Web Worker)

Claire·2024년 10월 18일

웹 워커(Web Worker)

웹 워커

자바스크립트 코드를 백그라운드에서 실행시키기 위한 기술로 다른 말로는 스레드라고도 부른다. 기존 웹표준에서는 멀티 스레드가 지원되지 않았는데, 이러한 멀티 스레드의 역할을 웹 워커가 담당하면서 별개의 백그라운드 처리가 가능해졌다.
(멀티 스레드란: 여러 작업을 동시에 수행하는 것)

웹워커의 생성 및 사용법

  • 워커의 생성 방법: HTML 페이지 안에서 Worker라는 객체를 통해 생성
  • new 연산자를 통해 객체를 생성, 전달 인자로 worker.js를 넘겨주어야 한다.
                                      var worker = new Worker("worker.js")

워커 객체를 통해 제공되는 메소드와 이벤트

  1. 워커 동작
  • postMessage(): 메인 문서와 워커 코드 사이에서 메세지를 보내거나 받을 때 사용하는 메소드로 메세지의 속성은 문자열 또는 json 객체
     worker.postMessage(메세지);
     // postMessage() 메소드에 메세지를 전달인즈로 넘기며, 이 메세지는 워커로 전달되다.
  • terminate(): 워커의 작업을 중지하게 하는 메소드
  • onnessage: 메세지를 리스닝하는 이벤트로 메인 문서는 워커 코드가 보낸 메세지를 수신
onmessage = function(event) {
	event.data;
    postMessage(메세지);
}

postMessage() 메소드에 의해 전달된 메세지를 event로 받고, postMessage()를 통해 메세지를 전달한 곳으로 다시 전달 가능

<이미지>
HTML5 메인 문서와 웹워커 사이에 postMessage() 메소드를 통해서 서로 양방향 메세지를 주고 받을 수 있다.

  1. 에러처리
  • 코드의 양이 많아져 복잡도가 증가하면 이에 대한 오류를 검출하기가 쉽지 않은데, 웹 워커는 에러를 확인하고 에러 정보를 리턴하는 이벤트를 제공한다
onerror = function(error){
	오류에 관한 정보 출력
}
  1. 워커 종료
  • terminate(): 메인 코드에서 워커 종료
  • close(): 워커 내부에서 워커를 종료

웹워커 예시 코드

index.html

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>바닐라로 워커 스레드 만들기</title>
  </head>
  <body>
    <button onclick="stopOperation()">워커 미적용 수행</button>
    <button onclick="applyWorker()">워커 수행</button><p></p>
    <button onclick="awake()">깨어날 시간</button><p></p>
    <button onclick="killWorker()">워커 종료</button><p></p>
    <button onclick="closeWorker()">워커 내부 종료</button>
    <p></p>
    <div id="result"></div>

    <script src="index.js"></script>
  </body>
</html>

index.js

const result = document.getElementById("result");

// function stopOperation() {
//   const endTime = new Date().getTime() + 5000; // 현재시간보다 5초 뒤
//   while (new Date().getTime() < endTime); // 현재 시간이 5초뒤를 가리키는 endTime보다 작을 때 true
//   result.innerHTML = "";
//   result.innerHTML = "일어날 시간입니다.";
// }

function awake() {
  alert("얘기야 가자");
}

// 워커 사용
function applyWorker() {
  if (window.Worker) {
    worker = new Worker("worker.js");
    worker.postMessage("일어나, 일어나라고!!!");

    worker.onmessage = function (event) {
      result.innerHTML = event.data;
    };

    worker.onerror = function (e) {
      result.innerHTML += `${e.message}가 발생했습니다.`;
      result.innerHTML += `${e.filename}에서 에러가 발생했습니다.`;
      result.innerHTML += `${e.lineno}에서 에러가 발생했습니다.`;
    };
  } else {
    result.innerHTML = "동작 실패 ㅠㅠ";
  }
}

function killWorker() {
  worker.terminate();
  result.innerHTML = "워커 종료";
}

function closeWorker() {
  worker.postMessage("close");
}

worker.js

function stopOperation() {
  const endTime = new Date().getTime() + 5000; // 현재시간보다 5초 뒤
  while (new Date().getTime() < endTime); // 현재 시간이 5초뒤를 가리키는 endTime보다 작을 때 true
}

onmessage = function (event) {
  const receiveMsg = event.data;
  stopOperation();
  const sendMsg = receiveMsg + "백그라운드에서 동작합니다.";
  this.postMessage(sendMsg);
};
profile
SEO 최적화 마크업 개발자입니다.

0개의 댓글