worker
웹 워커(Web worker) API는 스크립트 연산을 웹 어플리케이션의 주 실행 스레드와 분리된 별도의 백그라운드 스레드에서 실행할 수 있는 기술
단일 스레드 기반의 자바스크립트도 이 웹 워커 API 를 사용하면 브라우저에서 멀티스레드 수행이 가능
main thread 에서는 window 가 GlobalScope이다. worker thread 는 main thread 의 window 와는 별도의 WorkerGlobalScope 를 가진다. 그래서 Window의 메서드나 DOM 조작은 불가능하다.
worker_threads
The node:worker_threads module enables the use of threads that execute JavaScript in parallel
const { worker, isMainThread } = require("worker_threads");
workerData
const worker = new Worker("./worker.js", {
workerData: {},
})
워커와 메인 스레드 간의 데이터 교환은 메시지 시스템을 사용한다. worker thread에서 main thread의 window에 직접 접근할 수 없기 때문이다.
Message System (postMessage, onmessage)
- postMessage()
postMessage(message)
postMessage(message, transfer)
postMessage(message, options)
message는 워커에게 전달할 객체
transfer는 소유권을 이전할 수 있는 이전 가능한 객체
Transferable objects : 한 컨텍스트에서 다른 컨텍스트로 전송할 수 있는 리소스를 소유한 객체
- ArrayBuffer
- MessagePort
- ReadableStream
- WritableStream
- TransformStream
- WebTransportReceiveStream
- WebTransportSendStream
- AudioData
- ImageBitmap
- VideoFrame
- OffscreenCanvas
- RTCDataChannel
- onmessage
self.onmessage = () => { }
onmessage 이벤트는 이벤트 소스를 통해 메시지가 수신될 때 발생
- data - 실제 메시지를 포함
- origin - 이벤트를 호출한 문서의 URL
- lastEventId - 이벤트 스트림에서 확인된 마지막 메시지의 식별자
양측 모두 postMessage() 메서드를 사용해 전송하고, onmessage 이벤트 처리기(메시지는 Message의 data 속성)를 사용해 수신한다. 전송하는 데이터는 복사(copied)하며 공유(shared)하지 않는다.
동기와 비동기
자바스크립트의 메인스레드인 이벤트루프는 싱글 스레드.
자바스크립트는 이벤트 루프만 독립적으로 실행하지 않고, Node.js나 멀티 쓰레드 환경에서도 실행됨. 동시성을 보장하는 비동기, 논블록킹(멈춤 방지) 작업은 Javascript 엔진 구동하는 웹 브라우저, 런타임 환경에서 담당한다.
비동기 처리를 위한 방법
- promise
자바스크립트 비동기 처리에 사용되는 객체
Callback 함수의 에러/예외처리 어려움, 중첩으로 인한 복잡도 증가 단점을 해결하기 위해 ES6에서 지원
프로미스를 사용하면 비동기 메서드에서 마치 동기 메서드처럼 값을 반환 가능
A Promise is in one of these states
:• Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
• Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
• Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
우선 Promise 로 관리할 비동기 작업을 만드는 제일 정석적인 방법 new Promise(...)
new Promise() 메서드 호출하면 대기 상태
new Promise();
const promise = new Promise ((resolve, reject) => {})
promise.then( //resolve가 호출되면 then
)
.catch( //reject가 호출되면 catch
)
.finally(//콜백 마치고 무조건 실행 finally
)
asyncTask 함수는 프로미스를 반환하며, 프로미스는 비동기 작업을 수행하고 1초 후에 성공(resolve)하거나 실패(reject)
- resolve 콜백: 비동기 작업이 성공적으로 완료되었을 때 호출
- reject 콜백: 비동기 작업이 실패했을 때 호출
function asyncTask() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true; // 이 값을 바꿔가며 성공/실패를 테스트합니다.
if (success) {
resolve("Task completed successfully");
} else {
reject("Task failed");
}
}, 1000);
});
}
asyncTask()
.then((result) => {
console.log(result); // 성공 시 출력
})
.catch((error) => {
console.error(error); // 실패 시 출력
});
2. 콜백함수
자바스크립트는 함수를 변수처럼 사용이 가능하다
함수를 함수의 인자로 넘기는 것이 가능함. 파라미터로 함수를 전달 받아, 함수의 내부에서 실행된다.
콜백함수를 사용하면 특정 로직이 끝났을 때 원하는 동작을 실행시킬 수 있다.
jQuery의 ajax 통신
function getData() {
var tableData;
$.get('https://domain.com/products/1', function(response) {
tableData = response;
});
return tableData;
}
console.log(getData());
callback : 비동기 로직의 결과값을 처리하기 위해서는 callback안에서만 처리를 해야한다. 콜백 밖에서는 비동기에서 온 값을 알 수가 없다. 비동기 로직 결과를 다음 비동기로 전달할 때 깊어져서(콜백 지옥) 가독성 떨어진다.
promise : 비동기에서 온 값이 promise 객체에 저장되기 때문에 코드 작성이 용이해진다. .then을 통해 코드 깊어지는 걸 방지하고 가독성을 높일 수 있다.
3. async & await
함수 앞에 async라는 예약어를 붙이고, 함수 내부 로직 중 비동기 처리 코드 앞에 await을 붙인다. 비동기처리 메서드가 꼭 프로미스 객체를 반환해야 await가 의도한 대로 동작한다.
function앞에 async를 붙이면 해당 함수는 항상 프로미스를 반환. 화살표 함수에도 async가능
await은 async 함수 안에서만 동작, 자바스크립트는 await 키워드를 만나면 프로미스가 처리될 때까지 기다리고, 결과는 그 이후에 반환됨.
- 예외처리
try…catch..구문 사용
Promise에서는 .catch() async/await에선 catch{}
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function print() {
try {
await delay(2000);
return 1;
} catch (e) {
console.log(e);
}
}
console.log("start");
print().then((result) => {
console.log(result);
console.log("end");
});
setTimeout 함수는 주어진 시간(ms) 후에 resolve를 호출하여 프로미스를 해결한다.
delay 함수는 주어진 시간(ms)만큼 지연된 후에 해결되는 프로미스를 반환
결과 : start가 즉시 출력되고, 2초 후에 “1” “end” 순서대로 출력된다.
- 그냥 print().then()을 찍어보면
print는 async 함수이므로 호출될 때 즉시 프로미스를 반환
.then()은 새로 생성된 프로미스 객체를 반환하며, 선택적으로 연쇄에 사용할 수 있다.
console.log(print().then()); //Promise { <pending>}
- setTimeout 함수
Web API의 한 종류, 코드를 바로 실행하지 않고 지정한 시간만큼 기다렸다가 로직을 실행
console.log('Hello');
setTimeout(function() {
console.log('Bye');
}, 3000);
console.log('Hello Again');
//‘Hello’ 출력
//‘Hello Again’ 출력
//3초 있다가 ‘Bye’ 출력
- setTimeout 은 인자로 들어온 콜백 함수를 예약하기만 하고 바로 끝난다.
- setTimeout 에 의해 기다리는 동작은 본래의 코드 흐름과는 상관 없이 따로따로 독립적으로 돌아간다.
Reference
web workers api
https://developer.mozilla.org/ko/docs/Web/API/Web_Workers_API
https://nodejs.org/api/worker_threads.html
onmessage 이벤트
https://www.w3schools.com/jsref/event_onmessage_sse.asp
single-thread/multi-thread
https://velog.io/@jjunyjjuny/멀티-스레드-비동기-병렬-처리
동기 비동기 await, async, promise
https://hi-zini.tistory.com/entry/비동기적-방식-처리-방법-Callback-Promise-async-await
https://joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/
https://springfall.cc/article/2022-11/easy-promise-async-await
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
'JS.TS' 카테고리의 다른 글
TS의 런타임과 interface type (0) | 2025.03.11 |
---|---|
javascript로 XML 태그, 속성 분석하기 (1) | 2024.07.17 |
객체 배열과 인스턴스 메소드 / 정규 표현식과 match, parseInt / 문자열 포맷팅 (1) | 2024.07.15 |
JS 모듈 (CommonJS 모듈 / ES 모듈) (1) | 2024.06.26 |
자바스크립트 기본 문법 (자료형) (0) | 2024.06.25 |