Learning
레슨 6 / 9·20분

비동기 프로그래밍

동기 vs 비동기

JavaScript는 싱글 스레드이지만, 비동기 처리를 통해 네트워크 요청이나 타이머 같은 시간이 걸리는 작업을 블로킹 없이 수행합니다. 콜백, Promise, async/await 세 가지 방식으로 비동기를 다룹니다.

javascript
// 동기 — 순서대로 실행
console.log("1");
console.log("2");
console.log("3");
// 출력: 1, 2, 3

// 비동기 — setTimeout은 나중에 실행
console.log("1");
setTimeout(() => console.log("2"), 1000);
console.log("3");
// 출력: 1, 3, (1초 후) 2

Promise

Promise는 "미래에 완료될 작업"을 나타내는 객체입니다. resolve(성공)와 reject(실패) 두 가지 결과를 가지며, .then().catch()로 후속 처리를 합니다.

javascript
// Promise 생성
function delay(ms) {
  return new Promise((resolve) => {
    setTimeout(() => resolve("완료!"), ms);
  });
}

delay(1000)
  .then(result => console.log(result))  // "완료!"
  .catch(err => console.error(err));

// Promise 체이닝
fetch("https://api.example.com/users")
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error("에러:", err))
  .finally(() => console.log("요청 완료"));

async / await

async/await는 Promise를 더 읽기 쉽게 작성하는 문법입니다. async 함수 안에서 await를 사용하면 Promise가 해결될 때까지 기다린 후 다음 줄을 실행합니다.

javascript
// async/await 기본
async function fetchUser(id) {
  try {
    const res = await fetch("https://api.example.com/users/" + id);
    if (!res.ok) throw new Error("HTTP " + res.status);
    const user = await res.json();
    console.log(user.name);
    return user;
  } catch (err) {
    console.error("사용자 조회 실패:", err.message);
  }
}

// 병렬 실행 — Promise.all
async function fetchMultiple() {
  const [users, posts] = await Promise.all([
    fetch("/api/users").then(r => r.json()),
    fetch("/api/posts").then(r => r.json()),
  ]);
  console.log(users.length, posts.length);
}
  • Promise.all([...]) — 모두 성공해야 완료, 하나라도 실패하면 즉시 reject
  • Promise.allSettled([...]) — 성공/실패 관계없이 모두 완료 후 결과 반환
  • Promise.race([...]) — 가장 먼저 완료(성공 또는 실패)된 결과 반환
  • Promise.any([...]) — 가장 먼저 성공한 결과 반환
💡

await는 반드시 async 함수 안에서만 사용할 수 있습니다. 최상위 레벨에서는 모듈(type="module") 스크립트에서만 top-level await가 가능합니다.