자바스크립트는 단일 쓰레드(single-threaded) 언어이다. 이는 자바스크립트 엔진이 한 번에 하나의 작업만 처리할 수 있다는 것을 의미한다.
다른 많은 프로그래밍 언어들은 멀티 쓰레드(multi-threaded)를 지원하여 동시에 여러 작업을 처리할 수 있다. 멀티 쓰레드 언어에서는 한 쓰레드가 작업을 처리하는 동안에도 다른 쓰레드가 다른 작업을 처리할 수 있다.
그러나 자바스크립트는 단일 쓰레드 언어이므로 한 번에 하나의 작업만 처리할 수 있다. 이는 자바스크립트 코드가 순차적으로 실행되는 것을 의미한다. 자바스크립트는 이벤트 루프(event loop)와 비동기 콜백(callback)을 통해 비동기적인 작업을 처리할 수 있게 한다.
이벤트 루프는 콜백 함수를 대기열에 추가하고, 대기열의 작업이 완료되면 순차적으로 실행하는 방식으로 동작한다.
단일 쓰레드로 동작하는 자바스크립트의 장점은 코드 실행 순서를 예측하기 쉽고, 동시성 관련 문제를 처리하기 간단하다는 것이다.
하지만 복잡한 계산이나 처리량이 많은 작업을 처리할 때는 단일 쓰레드로 인해 성능 저하가 발생할 수 있다.
간단한 예시를 보자.
console.log("시작");
setTimeout(function() {
console.log("타이머 콜백 함수");
}, 2000);
console.log("끝");
위 코드는 "시작"을 출력한 뒤, 2초 후에 "타이머 콜백 함수"를 출력한다. 마지막으로 "끝"을 출력한다.
이 코드에서 `setTimeout` 함수는 지정된 시간인 2초가 지난 후에 콜백 함수를 실행한다. 자바스크립트는 단일 쓰레드로 동작하기 때문에 콜백 함수를 기다리는 동안 다른 작업을 처리할 수 없기에 "타이머 콜백 함수"는 "끝"을 출력한 뒤에야 실행된다.
만약 자바스크립트가 멀티 쓰레드로 동작한다면, "타이머 콜백 함수"는 2초 동안 대기하는 동안에도 다른 작업을 처리할 수 있어야 했을 것이다. 그러나 단일 쓰레드로 동작하는 자바스크립트는 이러한 순차적인 실행 방식을 따르기 때문에 "타이머 콜백 함수"는 이전 작업이 모두 완료된 후에 실행된다.
여기서 비동기 처리와의 개념이 충돌나 헷갈릴 수 있다.
비동기 처리는 여러 작업을 동시에 처리할 수 있는 기능을 제공하지만, 자바스크립트의 단일 쓰레드 특성으로 인해 실제로는 각 작업을 빠르게 번갈아가면서 실행하는 것이다.
비동기 처리는 일반적으로 콜백 함수, 프로미스(Promise), async/await 등을 사용하여 구현된다. 비동기 작업은 메인 스레드의 실행을 차단하지 않고 백그라운드에서 동작하며, 작업이 완료되면 결과를 처리하는 콜백 함수나 프로미스 체인을 통해 알림을 받을 수 있다.
예를 들어, 다음은 비동기적으로 이미지를 불러오고, 불러온 이미지를 화면에 표시하는 예시 코드를 보자
console.log("시작");
function loadImage(url) {
return new Promise((resolve, reject) => {
const image = new Image();
image.onload = () => resolve(image);
image.onerror = () => reject(new Error("이미지를 불러올 수 없습니다."));
image.src = url;
});
}
async function displayImage() {
try {
const image = await loadImage("image.jpg");
document.getElementById("myImage").src = image.src;
console.log("이미지 표시 완료");
} catch (error) {
console.error(error);
}
}
displayImage();
console.log("끝");
위 코드에서 loadImage 함수는 이미지를 비동기적으로 불러오는 작업을 수행한다. displayImage 함수는 await를 사용하여 이미지 로드가 완료될 때까지 기다린 후, 로드된 이미지를 화면에 표시한다.
비동기 작업인 이미지 로드는 메인 스레드의 실행을 차단하지 않고 백그라운드에서 수행되므로, 다른 작업을 처리할 수 있다. 하지만 자바스크립트는 여전히 단일 쓰레드로 동작하므로, 비동기 작업이 진행되는 동안에도 다른 작업을 동시에 처리하는 것은 불가능하다.
[참고 문헌]
https://developer.mozilla.org/en-US/docs/Glossary/Thread
'Basic > JavaScript' 카테고리의 다른 글
[Javascript] 문자열 자리수 채우기 - padStart, padEnd (0) | 2023.08.17 |
---|---|
데이터 캐싱으로 웹소켓 성능 개선하기 (불필요한 네트워크 트래픽 없애기) (0) | 2023.05.10 |
[JavaScript] 세미콜론 자동 삽입(Automatic Semicolon Insertion, ASI) 주의하기 - 코드 컨벤션 (0) | 2023.05.09 |
[JavaScript] 익명함수와 화살표 함수 이해하기 (0) | 2023.05.09 |
[JavaScript] BigNumber.js를 활용하여 정확한 계산, 큰 수 및 작은 수 다루기 (0) | 2023.05.08 |