동기(Synchronous)와 비동기(Asynchronous)는 "코드가 실행되는 흐름(방식)"을 의미하는 기본 개념이에요.
특히 자바스크립트(JavaScript)에서는 단일 스레드(single-threaded) 기반의 언어이기 때문에, 한 번에 하나의 작업만 할 수 있어요. 그래서 이 개념이 아주 중요합니다.
1. 동기(Synchronous)
✔ 정의
한 작업이 완전히 끝나야 다음 작업을 실행하는 방식
자바스크립트는 기본적으로 동기적으로 실행됩니다.
즉, 코드는 한 줄씩 순서대로 실행돼요.
📋 예시
console.log('1');
console.log('2');
console.log('3');
결과:
1
2
3
⚠️ 단점
- 만약 한 작업이 오래 걸리면(예: 파일 읽기, API 요청 등)
→ 그 작업이 끝날 때까지 다른 작업이 멈춰버림 (블로킹 blocking)
예로 들어서 모든 작업을 동기 방식으로 처리한다면?
// 동기적으로 5초 걸리는 함수
function longTask() {
const now = Date.now();
while (Date.now() - now < 5000) {}
console.log('5초 후 실행됨');
}
console.log('A');
longTask();
console.log('B');
결과:
A
5초 후 실행됨
B
❌ 문제
- longTask가 끝날 때까지 B도, 사용자 인터랙션도 모두 멈춤
→ 브라우저가 ‘먹통’이 돼요.
그래서 JS는 시간이 오래 걸리는 작업(예: 서버 요청, 파일 읽기 등)을 비동기로 처리해요.
2. 비동기(Asynchronous)
✔ 정의
작업이 바로 끝나지 않아도, 다음 작업을 먼저 실행하고
결과가 준비되면 나중에 처리(callback) 하는 방식
즉, 비동기란 어떤 작업이 끝날 때까지 기다리지 않고 다음 작업을 먼저 실행하는 방식을 말해요.
JS는 사용자의 경험을 끊기지 않게 하기 위해,
IO 작업(서버 요청, 파일 읽기, 타이머 등)은 비동기적으로 처리해요.
❓ 왜 JS는 비동기를 중요하게 여길까?
자바스크립트는 기본적으로 단일 스레드(single-threaded)입니다.
즉, 동시에 여러 작업을 처리할 수 없어요. (병렬 처리❌)
그래서:
✅ 브라우저가 멈추지 않도록
✅ 사용자 인터페이스가 끊기지 않도록
→ 비동기 처리가 핵심이 된 거예요!
🔁 비동기 처리의 핵심 원리 (브라우저 런타임)
자바스크립트의 동작 구조
JS의 비동기 처리는 다음 구조에 기반합니다:
- Call Stack (호출 스택)
→ 동기 코드들이 순서대로 실행되는 공간 - Web APIs (브라우저 기능)
→ setTimeout, fetch, DOM 이벤트 같은 비동기 작업을 처리하는 별도의 시스템 - Callback Queue (이벤트 큐)
→ 비동기 작업이 끝난 후 실행될 함수들이 쌓이는 공간 - Event Loop (이벤트 루프)
→ 호출 스택이 비면, 큐에 있는 콜백을 꺼내와 실행해줌
📋 예시 (setTimeout)
console.log('A');
setTimeout(() => {
console.log('B');
}, 0);
console.log('C');
결과:
A
C
B
→ setTimeout()은 기다리지 않고, 등록만 한 후 다음 줄로 넘어감
setTimeout의 콜백은 브라우저의 Web API 영역에서 타이머가 끝난 후, 이벤트 큐로 이동
JS의 Event Loop는 스택이 비었을 때 큐에서 콜백을 꺼냄
그래서 C가 먼저 나오고 B가 나중에 출력됨
비동기로 동작하는 것들
사용처 | 콜백 함수가 실행되는 시점 |
setTimeout, setInterval | 타이머 만료 후 |
addEventListener | 이벤트 발생 후 |
XMLHttpRequest, fetch | 네트워크 응답 도착 후 |
fs.readFile (Node.js) | 파일 읽기 완료 후 |
🧰 비동기를 다루는 방법들
방식 | 설명 |
콜백 함수 (callback) | 작업 완료 후 호출되는 함수. 가장 기본적인 비동기 처리 방식 |
Promise | 비동기 결과(성공/실패)를 표현하는 객체 |
async/await | Promise를 더 쉽게, 동기처럼 다루는 문법 |
콜백함수가 바로 자바스크립트에서 모든 비동기 동작의 출발점입니다.
이를 바탕으로 Promise → async/await 으로 발전해나갔죠.
🧪 비동기 콜백 함수 예시(이벤트리스너)
const button = document.querySelector('#myButton');
button.addEventListener('click', () => {
console.log('버튼이 클릭되었어요!');
});
🧪 Promise 예시
function getData() {
return new Promise((resolve) => {
setTimeout(() => {
resolve("완료!");
}, 1000);
});
}
getData().then((result) => {
console.log(result); // 완료!
});
🧪 async/await 예시 (가장 읽기 쉬움)
async function fetchData() {
console.log("1");
const result = await getData(); // 비동기 작업 기다림
console.log(result); // 완료!
console.log("2");
}
동기 vs 비동기
📍 실생활 비유
동기 | 비동기 |
ATM 기계에 한 사람씩 줄 서기 | 음식 주문하고 테이블에서 기다리기 |
친구에게 전화 → 받을 때까지 기다림 | 친구에게 메시지 보내고, 답 올 때까지 다른 일 함 |
🔒 동기와 비동기의 차이 요약
구분 | 동기(sync) | 비동기(async) |
실행 순서 | 순차적으로 끝날 때까지 | 기다리지 않고 다음 코드 실행 |
코드 흐름 | 예측 가능 | 이벤트 기반, 흐름 제어 필요 |
멈춤 여부 | 오래 걸리면 전체 코드 멈춤 | 코드 흐름 멈추지 않음 |
예 | console.log(), 계산 | fetch(), setTimeout(), 파일 읽기 |
⭐️ 비동기 요약
항목 | 설명 |
비동기란 | 기다리지 않고, 다른 작업을 먼저 수행하는 방식 |
JS에서 필요한 이유 | 단일 스레드이기 때문에 멈추지 않게 하려고 |
처리 방식 | Callback → Promise → async/await |
작동 원리 | Call Stack, Web APIs, Callback Queue, Event Loop |
✨ 마무리
- 자바스크립트는 단일 스레드라서 비동기 처리가 중요합니다.
- 비동기 개념을 이해해야, fetch가 왜 바로 결과를 안 주는지, 왜 async/await이 필요한지, 왜 콜백 지옥이 나오는지 등 모든 흐름이 보이기 시작합니다.
'CS' 카테고리의 다른 글
쿠키(Cookie) vs localStorage vs sessionStorage 제대로 알고 쓰기 (0) | 2025.06.26 |
---|---|
콜백은 왜 불편했을까? 자바스크립트 비동기의 발전 과정 한눈에 보기 (2) | 2025.06.25 |
CORS 에러가 뭔데 자꾸 막는 건데? (프록시로 뚫자!) (1) | 2025.06.25 |
이벤트 위임(Event Delegation)이란? 성능과 유지보수를 동시에 잡는 방법 (2) | 2025.06.24 |
클로저, 그냥 이 글 하나로 끝내자 (일급 객체 + 렉시컬 스코프 쉽게 정리) (0) | 2025.06.24 |