본문 바로가기
C.W.K.
Stream
Lesson 02 of 05 · published

`async`와 `await`: 비동기 흐름의 타입 읽기

~8 min · async-promises, async-await, syntax

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"await는 비동기를 동기로 바꾸지 않아. 다음 줄을 이어 쓸 수 있게 흐름을 풀어 줄 뿐이야."

async 함수의 반환 타입

async function load(): User라고 쓰는 것이 아니라 Promise<User>를 반환한다고 선언해야 해. 함수 본문에서 return user라고 해도 호출자는 즉시 User가 아니라 Promise를 받기 때문이야. 반환값이 없다면 Promise<void>가 돼.

추론이 잘 되는 작은 함수는 반환 타입을 생략할 수 있지만, 공개 API나 재귀 비동기 함수에서는 명시하면 계약이 선명해져. 구현을 실수로 바꿨을 때 호출부까지 넓게 번지기 전에 함수 경계에서 막을 수도 있어.

await가 하는 타입 변환

const user = await load()에서 user는 User로 추론돼. Promise가 아닌 값에 await를 써도 그 값은 그대로 나오므로 문법상 가능하지만, 불필요한 await는 흐름을 오해하게 만들 수 있어. 병렬로 시작할 작업을 연달아 기다리면 성능도 달라지지.

서로 독립적인 요청은 먼저 Promise들을 만든 뒤 Promise.all로 함께 기다리고, 앞 결과가 뒤 입력에 필요한 경우에만 순차적으로 await해. 타입 안전과 실행 순서는 별개의 설계 축이야.

반환은 감싸고 Promise는 평평하게 해

async 함수에서 일반 값 42를 반환해도 공개 결과는 Promise<number>로 감싸져. 이미 Promise<User>인 값을 반환하면 결과를 다시 중첩하지 않고 그대로 Promise<User>로 평평하게 해.

Promise가 아닌 값을 await하면

await 42처럼 일반 값을 기다리면 런타임이 Promise.resolve처럼 처리해 같은 42를 돌려줘. 명시적으로 쓸 일은 드물지만 await가 입력을 어떻게 다루는지 보여 주는 규칙이야.

async와 await는 Promise 흐름을 읽기 좋게 만드는 문법이야. 병렬성, 취소, 오류 책임은 자동으로 해결되지 않으니 코드에 따로 드러내.

Code

async wrap, await unwrap·typescript
// async 가 return 을 Promise<T> 로 wrap.
async function getNumber(): Promise<number> {
  return 42;                          // wrap → Promise<number>
}

// Promise return — flatten.
async function getUser(): Promise<User> {
  return fetchUser(1);                // Promise<User> 반환, Promise<Promise<User>> 아님
}

// await — async 함수에서만 unwrap.
async function main() {
  const n = await getNumber();        // n: number
  const u = await getUser();          // u: User

  // Non-Promise 에 await — 그냥 값 반환.
  const x = await 42;                  // x: number
}

// Top-level await — ESM 에 작동, default 로 CommonJS 안 됨.
const data = await fetch('/api/data');  // modern ESM module 에 유효

External links

Exercise

사용자와 게시물을 차례로 기다린 뒤 Profile을 반환하는 loadProfile을 작성해. 각 await 뒤의 지역 변수가 Promise가 아닌 실제 값 타입인지 확인해.
Hint
await fetchUser(id)는 Promise<User>에서 User를 꺼내. 일반 객체를 반환해도 async 함수의 공개 결과는 다시 Promise<Profile>이 돼.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인 — 댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.