TYPESCRIPT · 심층 가이드
TypeScript 비동기/동시성 완전 정리
async 함수는 호출되는 순간 이미 실행을 시작하므로, 같은 코드가 순차가 되느냐 병렬이 되느냐는 await를 어느 지점에 두느냐라는 한 가지 선택으로 갈립니다.
TypeScript가 도는 런타임은 대부분 단일 스레드이고, 동시성은 스레드가 아니라 이벤트 루프에 얹힌 대기로 구현됩니다. 여기서 모델이 깨지는 자리는 Promise의 생성 시점입니다. Promise는 만들어지는 즉시 작업을 시작하며 await는 결과를 기다릴 뿐입니다. 그래서 반복문 안에서 곧바로 await하면 전부 직렬로 늘어서고, 먼저 전부 만들어 두었다가 Promise.all로 모으면 같은 코드가 병렬이 됩니다.
비동기 함수 시작에서 반환 타입이 항상 Promise로 감싸진다는 사실을 확인한 뒤, 순차 작업 처리와 병렬 작업 처리를 나란히 놓고 코드 모양은 비슷한데 실행 시간이 왜 달라지는지를 봅니다. 그 위에 timeout 처리와 retry 로직이 얹히는데, 둘 다 원래 작업을 그대로 두고 바깥에서 감싸는 래퍼라는 점이 같습니다. 취소 신호까지 오면 시작·대기·중단이라는 세 축이 모두 갖춰지고, 나머지 주제는 이 조합의 변형으로 읽힙니다.
Promise.all은 하나가 거부되면 즉시 거부되지만 나머지 작업은 계속 돕니다. 중단된 것이 아니라 결과를 아무도 받지 않을 뿐이라, 뒤늦게 실패하면 처리되지 않은 거부가 되고 열어 둔 연결이나 파일이 그대로 남습니다. 전부의 성패를 알아야 한다면 Promise.allSettled를, 자원을 실제로 놓아야 한다면 AbortController를 함께 씁니다. 타임아웃 래퍼도 같은 이유로 원래 작업을 멈추지는 못합니다.
01비동기 함수 시작
TypeScript에서 비동기 함수 시작 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 비동기 함수 시작
async function run(): Promise<void> {
const value = await Promise.resolve(1);
console.log(value);
}
run();비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
02순차 작업 처리
TypeScript에서 순차 작업 처리 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 순차 작업 처리
Promise.all([Promise.resolve("a"), Promise.resolve("b")]).then(console.log);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
03병렬 작업 처리
TypeScript에서 병렬 작업 처리 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 병렬 작업 처리
const controller = new AbortController();
controller.abort();
console.log(controller.signal.aborted);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
04timeout 처리
TypeScript에서 timeout 처리 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// timeout 처리
setTimeout(() => console.log("tick-4"), 10);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
05retry 로직
TypeScript에서 retry 로직 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// retry 로직
async function run(): Promise<void> {
const value = await Promise.resolve(5);
console.log(value);
}
run();비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
06스트림 또는 채널 소비
TypeScript에서 스트림 또는 채널 소비 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 스트림 또는 채널 소비
Promise.all([Promise.resolve("a"), Promise.resolve("b")]).then(console.log);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
07producer consumer
TypeScript에서 producer consumer 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// producer consumer
const controller = new AbortController();
controller.abort();
console.log(controller.signal.aborted);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
08취소 신호
TypeScript에서 취소 신호 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 취소 신호
setTimeout(() => console.log("tick-8"), 10);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
09비동기 에러 처리
TypeScript에서 비동기 에러 처리 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 비동기 에러 처리
async function run(): Promise<void> {
const value = await Promise.resolve(9);
console.log(value);
}
run();비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
10배치 처리
TypeScript에서 배치 처리 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 배치 처리
Promise.all([Promise.resolve("a"), Promise.resolve("b")]).then(console.log);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
11debounce
TypeScript에서 debounce 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// debounce
const controller = new AbortController();
controller.abort();
console.log(controller.signal.aborted);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
12throttle
TypeScript에서 throttle 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// throttle
setTimeout(() => console.log("tick-12"), 10);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
13파일 읽기 작업
TypeScript에서 파일 읽기 작업 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 파일 읽기 작업
async function run(): Promise<void> {
const value = await Promise.resolve(13);
console.log(value);
}
run();비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
14요청 작업 감싸기
TypeScript에서 요청 작업 감싸기 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 요청 작업 감싸기
Promise.all([Promise.resolve("a"), Promise.resolve("b")]).then(console.log);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
15스케줄 작업
TypeScript에서 스케줄 작업 개념을 코드로 빠르게 확인하는 비동기/동시성 예제입니다.
TypeScript code
// 스케줄 작업
const controller = new AbortController();
controller.abort();
console.log(controller.signal.aborted);비동기 예제는 순차 실행과 병렬 실행이 실제로 어떻게 다른지 같이 관찰해 보세요.
비동기처럼 보이는 코드도 실제로는 순차 실행일 수 있으니 흐름을 꼭 확인해야 합니다.
정리하며
- 반복문 안의
await는 직렬 실행이니 병렬이 필요하면 먼저 배열로 모읍니다. Promise.all은 거부 시 나머지를 멈추지 않으므로 취소 신호를 따로 전달합니다.- 타임아웃은 대기만 끊을 뿐이라 실제 중단은
AbortController로 처리합니다. - 재시도는 네트워크 오류와 검증 실패를 구분해 재시도 대상만 다시 던지게 만듭니다.
더 깊이 들어가고 싶다면 TypeScript 학습 라이브러리에서 다른 주제 가이드를 이어서 보거나, 언어 비교에서 같은 개념이 다른 언어에서 어떻게 표현되는지 확인해 보세요.