요약
자바스크립트는 기본적으로 동기적으로 코드를 실행하지만, 시간이 오래 걸리는 작업(예: 백엔드와의 통신)을 효율적으로 처리하기 위해 setTimeout, Promise, async/await, fetch, 이벤트 리스너 등 비동기 처리 방식도 함께 제공한다.
자바스크립트는 기본적으로 동기적으로 코드를 실행하는 언어다.
블로킹(blocking) 방식 → 실행 중인 코드가 전체 흐름을 멈춘다.first(), second(), third() 함수를 순서대로 호출한다.
// 1 출력
const first = () => {
console.log(1);
console.log(new Date().toLocaleTimeString('ko-KR', {
hour12: false
}));
}
// 2 출력
const second = () => {
console.log(2);
console.log(new Date().toLocaleTimeString('ko-KR', {
hour12: false
}));
}
// 3 출력
const third = () => {
console.log(3);
console.log(new Date().toLocaleTimeString('ko-KR', {
hour12: false
}));
}
// 순차 호출
first();
second();
third();

first() 실행 → 1과 시간 출력second() 실행 → 2와 시간 출력third() 실행 → 3과 시간 출력이는 자바스크립트가 이전 작업이 끝나야 다음 작업을 실행하는 구조, 즉 동기 처리 방식이기 때문이다.
이런 동기적 구조에서는, 서버 통신이나 연산 시간이 오래 걸리는 작업이 전체 흐름을 멈추게 되어 사용자 경험에 부정적인 영향을 줄 수 있다. 서버에서 데이터를 받아오거나 연산 시간이 오래 걸리는 함수가 있다면 그 작업이 끝나기 전까지 다른 동작은 전혀 수행되지 않는다.
아래 코드는 second() 함수 내부에 10초 동안 멈추는 블로킹 작업을 의도적으로 삽입해, 전체 흐름이 중단되는 상황을 재현한 것이다.
// 1 출력
const first = () => {
console.log(1);
console.log(new Date().toLocaleTimeString('ko-KR', {
hour12: false
}));
}
// 10초 블로킹 후에 2 출력
const second = () => {
const start = Date.now();
while (Date.now() - start < 10000) { }
console.log("2");
console.log(new Date().toLocaleTimeString('ko-KR', {
hour12: false
}));
};
// 3 출력
const third = () => {
console.log(3);
console.log(new Date().toLocaleTimeString('ko-KR', {
hour12: false
}));
}
// 순차 호출
first();
second();
third();

first() 실행 → 1과 시간 출력second()에서 10초 동안 아무 동작도 하지 못함2 출력third() 실행 → 3과 시간 출력이처럼 오래 걸리는 작업이 있는 경우, 자바스크립트는 해당 작업이 끝나기 전까지 다음 작업을 실행하지 못하기 때문에 사용자 경험이 심각하게 저하될 수 있다.
블로킹과 논블로킹
블로킹 (Blocking)
하나의 작업이 완전히 끝날 때까지 다음 작업을 멈추고 기다리는 방식
논블로킹 (Non-blocking)
하나의 작업이 끝날 때까지 기다리지 않고, 다음 코드로 즉시 넘어가는 방식
시간이 오래 걸리는 작업은 백그라운드에서 처리하고, 다른 작업을 계속 수행 가능
자바스크립트는 setTimeout, Promise, async/await, fetch 등 비동기 처리 방식을 통해 오래 걸리는 작업을 백그라운드에서 처리할 수 있도록 지원한다.
// 1 출력
const first = () => {
console.log(1);
console.log(new Date().toLocaleTimeString('ko-KR', {
hour12: false
}));
}
// 10초 블로킹 후에 2 출력
const second = () => {
setTimeout(() => {
const start = Date.now();
while (Date.now() - start < 10000) { }
console.log("2");
console.log(new Date().toLocaleTimeString('ko-KR', {
hour12: false
}));
}, 0);
};
// 3 출력
const third = () => {
console.log(3);
console.log(new Date().toLocaleTimeString('ko-KR', {
hour12: false
}));
}
// 순차 호출
first();
second();
third();

first() 실행 → 1과 시간 출력second() 실행 → setTimeout() 실행setTimeout의 콜백 함수가 브라우저의 Web API 공간에 등록second() 함수 종료third() 실행 → 3과 시간 출력setTimeout의 콜백 함수를 콜스택으로 보냄2와 시간 출력setTimeout 덕분에 second() 작업이 뒤로 밀려났기 때문에, third()가 먼저 실행될 수 있었던 것이다.
setTimeout()
setTimeout()은 자바스크립트 Web API(브라우저 API) 중 하나로, 일정 시간이 지난 후 콜백 함수를 예약해두는 역할을 한다. 이 예약된 콜백 함수는 나중에 이벤트 루프(Event Loop)가 호출한다.
자바스크립트는 기본적으로 동기적 처리 방식이지만, 사용자 경험을 고려해 비동기 처리 방식도 함께 제공한다.
동기 처리는 실행 순서가 예측 가능하지만, 시간이 오래 걸리는 작업이 있으면 전체 흐름을 멈추는 단점이 있다.
비동기 함수 (setTimeout, Promise, fetch, async/await) 를 활용하면 전체 흐름을 멈추지 않고도 결과를 나중에 처리할 수 있어, 더 자연스럽고 반응성 좋은 사용자 경험을 만들 수 있다.