자바스크립트는 단일 스레드 언어로서 데이터 처리를 동기적으로 실행한다.
동기적 방식은 순차적으로 진행이 돼기 때문에 스트리밍 같은 시스템에서 동기적으로 할 시 불필요한 시간이 소요 될 수 있다.
그래서 비동기(순차적이지 않은)방식으로 데이터처리 하는 방법이 있다.
동기 처리
프로그래밍에서 코드가 순차적으로 작동하는 방식을 동기적 방식이라고한다.
동기적 방식은 순차적이기 때문에 간단하지만, 대형 데이터 처리의 경우 순차적으로 진행 될 경우 하나의 처리가 끝날 때까지 기다렸다 일을 진행하기 때문에 성능과 UX관점에서 효율이 좋지 않다.

비동기 처리
자바 스크립트는 웹에서 동적인 페이지를 만들기 위해 개발된 스크립트 언어다. 개발 당시에 복잡한 처리가 필요하지 않아 싱글 스레드로 구현 됐다. 그러나 싱글 스레드 방식은 하나의 작업만 처리가 가능하기 때문에 이를 해결하기 위해 이벤트 루프를 이용한 비동기적 처리를 활용한다.

이벤트 루프
이벤트 루프는 자바 스크립트 엔진 내부의 비동기식 처리 흐름을 제어하는 구조로써 콜스택(Call Stack), 백그라운드(Background)이벤트 큐(Event Queue)로 구성이 돼있다.
콜 스택
- 자바 스크립트 엔진이 실행할 함수를 추적하는 스택 구조다
- 함수가 호출 되면 콜 스택에 추가되고, 함수가 종료되면 콜 스택에서 제거 된다.
- 동기적으로 실행되는 모든 코드는 콜 스택에서 처리 된다.
- 콜스택이 비어 있으면 실행중인 함수가 없을 때 이벤트 루프는 테스크 큐(이벤트 큐)에서 다음작업을 가져와 콜 스택에 넣는다.
백그라운드
- 자바스크립트 엔진 외부의 환경인 브라우저의 웹 API나 Node.js와 같은 환경에서 비동기 작업을 실제로 처리하는 영역
- setTimeout 같은 비동기 함수의 콜백함수를 백그라운드에서 처리하고, 작업이 완료 될 때 까지 대기시킨다.
- 백그라운드 작업이 완료되면, 해당 작업의 콜백 함수가 태스크 큐로 전달 된다.
태스크 큐
- 백그라운드에서 작업이 완료되고 그 결과를 처리할 콜백 함수들이 대기하는 큐
- 콜 스택이 비어 있을 때, 이벤트 루프는 태스크 큐에 대기중인 콜백을 콜 스택으로 가져와 실행한다.

프로미스(Promise)
Promise 객체는 이벤트 루프가 실행하는 작업중에 하나로 비동기 작업의 완료 여부를 추적한다.
작업 순서
동기 코드 실행
처음에는 모든 동기적인 코드들이 콜 스택에서 순차적으로 실행됩니다.
비동기 작업 대기
동기 코드 중에서 시간이 오래 걸리는 비동기 작업(네트워크 요청 등)은 이벤트 루프에 의해 백그라운드 작업으로 넘어가며, 동시에 비동기 작업이 시작되면 프로미스 객체가 생성됩니다.
콜 스택 종료
동기 코드가 모두 실행된 후 콜 스택이 비게 되면, 이벤트 루프는 이벤트 큐에 대기 중인 비동기 작업들을 처리합니다.
프로미스 처리
비동기 작업이 완료되면, 프로미스는
resolved
또는 rejected
상태가 되어 이벤트 큐로 넘어가고, 이벤트 루프가 이를 처리합니다.예제 코드
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Async Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body>
<h2>JavaScript Asynchronous Examples</h2>
<p id="demo"></p>
<script>
console.log("1: Synchronous Code");
// 비동기 처리 (setTimeout 예시)
setTimeout(() => {
console.log("3: Timeout after 2s");
}, 2000);
console.log("2: Synchronous Code");
// Promise 예시 (비동기 처리)
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("5: Promise Resolved after 3s");
}, 3000);
});
myPromise.then((message) => {
console.log(message);
});
console.log("4: Synchronous Code After Promise");
// async/await 예시
async function asyncFunction() {
console.log("6: Before Await");
const result = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("7: Awaited Result after 4s");
}, 4000);
});
console.log(result);
console.log("8: After Await");
}
asyncFunction();
</script>
</body>
</html>

- setTimeout:
"3: Timeout after 2s"
는 2초 후에 실행되는 비동기 작업입니다.
- Promise: 프로미스 객체는 비동기 작업을 나타낸다.
"5: Promise Resolved after 3s"
는 프로미스가 3초 후에 해결(resolved)될 때 실행되는 코드다.
- async/await: 비동기 함수 안에서
await
을 사용해 프로미스가 해결될 때까지 기다린 후 결과를 출력한다."6: Before Await"
,"7: Awaited Result after 4s"
,"8: After Await"
순서대로 실행된다.
Share article