비동기
기다림 많은 일을 멈추지 않고 처리하는 법.
한눈에
- 비동기 = 기다리는 시간에 다른 일 하기 (라면 끓는 동안 설거지)
- 동기 = 앞사람 끝나야 내 차례 (냄비만 쳐다보며 대기)
- 콜백 = 끝나면 이 함수 불러줘 (겹치면 콜백 지옥)
- 프로미스 = 나중에 값이 담길 상자 (.then() 체인, .catch() 에러)
- async/await = 비동기를 동기처럼 위에서 아래로 (지금 표준, 속은 프로미스)
- 프로미스 = Java의 Future (단 await는 스레드를 멈춰 세우지 않는다)
라면을 끓인다고 하자. 물을 올려놓고 냄비만 뚫어지게 쳐다보며 서 있는 사람은 없다. 끓는 동안 설거지를 하고, 빨래를 돌리고, 그러다 물이 끓으면 그때 면을 넣는다. 이게 비동기다. 반대로 냄비 앞에 딱 붙어 다 끓을 때까지 아무것도 안 하고 서 있는 게 동기다. 한 줄로 하면, 비동기는 "기다리는 시간에 다른 일을 하는" 방식이다.
동기와 비동기
동기(synchronous)는 줄을 선다. 앞사람 일이 끝나야 내 차례가 온다. 은행 창구가 한 줄뿐이면, 앞 손님 업무가 30분 걸릴 때 뒤는 그냥 멈춰서 기다린다. 코드로 치면 한 줄이 끝나야 다음 줄이 실행되는 것.
비동기(asynchronous)는 맡겨두고 다음 일을 한다. 번호표를 뽑고 자리에 앉아 다른 일을 보다가, 내 번호가 불리면 그때 창구로 간다. 창구가 여러 손님을 병렬로 굴리는 동안 나도 멈추지 않는다.
왜 굳이 이렇게
핵심은 기다림이 많은 작업이다. 파일 읽기, 네트워크 요청, DB 조회 — 이건 내 프로그램이 열심히 계산하는 게 아니라 결과가 올 때까지 그냥 기다리는 일이다. 이걸 동기로 처리하면 기다리는 내내 프로그램 전체가 멈춘다. 손님 100명이 각자 파일 하나씩 읽어달라고 하는데, 한 명 끝날 때까지 나머지 99명이 대기하는 꼴.
비동기면 다르다. A의 파일 읽기를 걸어두고 — 기다리지 않고 — 바로 B를 처리하고, C를 처리하다가, "A 파일 다 읽었어요" 하면 그때 A에게 돌려준다. 기다림이 많을수록 이 방식이 압도적으로 유리하다.
콜백 → 프로미스 → async/await
비동기는 결국 **"결과가 오면 이걸 해줘"**를 어떻게 적느냐의 문제다. 이 표현법이 세 단계로 진화했다.
콜백이 처음이었다. "끝나면 이 함수를 불러줘" 하고 함수를 넘긴다. 하나면 깔끔한데, 순서대로 여러 개를 엮으면 문제가 생긴다. A 끝나면 B, B 끝나면 C, C 끝나면 D... 함수 안에 함수가 계단처럼 겹겹이 쌓인다. 이게 악명 높은 콜백 지옥이다. 오른쪽으로 밀려나는 코드는 읽기도, 에러 잡기도 지옥이다.
**프로미스(Promise)**가 이걸 폈다. "나중에 값이 담길 상자"를 먼저 돌려주는 것. .then()으로 이어붙이면 계단이 세로 체인으로 펴진다. .catch()로 에러도 한곳에서 잡는다.
async/await가 마지막이자 지금 표준이다. 비동기인데 동기처럼 위에서 아래로 읽힌다. await를 붙이면 "여기서 결과를 기다렸다가 다음 줄로" 라는 뜻인데, 겉보기엔 평범한 순차 코드라 눈에 제일 편하다. 속은 여전히 프로미스다.
Java 하던 사람 기준 다리
낯선 개념이 아니다. Java에도 다 있던 것이고, 자리만 조금 다르다.
여기서 한 가지 감각 차이가 크다. Java에서 "비동기"라고 하면 보통 스레드를 하나 더 띄워 옆에서 돌리는 그림을 떠올린다. 자바스크립트의 비동기는 그게 아니라, 한 스레드가 기다림을 저글링하는 방식이다. 그래서 스레드를 새로 파던 습관을 그대로 옮기면 오히려 어색하다 — 여기선 그냥 await를 걸어두면 런타임이 알아서 다른 일로 넘어간다.
우리 프로젝트에선
이 0to1 블로그를 굴리는 Node 스크립트들이 전부 비동기로 짜여 있다. 파일을 읽고, git 로그를 긁고, 글 목록과 신선도 점수를 만드는 일 — 죄다 "기다림이 많은 작업"이라 비동기가 자연스럽게 온다.
사실 비동기는 Node 노트의 이벤트 루프와 한 몸인 개념이다. 이벤트 루프가 "기다리며 멈추지 않고 저글링하는 심장"이고, 비동기는 그 심장이 굴리는 일 처리 방식이다. 콜백·프로미스·async/await는 그 저글링을 코드로 어떻게 적느냐의 문제일 뿐이다. 그래서 둘은 같이 봐야 그림이 맞는다 — 심장 쪽이 궁금하면 Node로.
더 읽기
비유와 예제로 더 풀어놓은 글들. 진화 순서대로 하나씩 따라가면 좋다.
- 자바스크립트 비동기 처리와 콜백 함수 — 캡틴판교 — 비동기가 뭔지, 콜백과 콜백 지옥까지 초보 눈높이로
- 비동기, Promise, async, await 확실하게 이해하기 — 봄가을 — 어부 마을 비유로 프로미스를 낱낱이
- 자바스크립트 async와 await — 캡틴판교 — 가장 최근 문법인 async/await를 예제와 예외 처리까지