YJ Blog
JavaScript

JavaScript 비동기 프로그래밍: Promise와 async/await

0회 조회

JavaScript 비동기 프로그래밍: Promise와 async/await

자바스크립트는 단일 스레드 언어이지만, 비동기 처리로 네트워크 요청, 파일 읽기 등을 효율적으로 처리합니다.

콜백의 문제점

// 콜백 지옥
getUser(id, (user) => {
  getPosts(user.id, (posts) => {
    getComments(posts[0].id, (comments) => {
      // 깊어질수록 유지보수가 어려워짐
    })
  })
})

Promise

function fetchUser(id) {
  return new Promise((resolve, reject) => {
    fetch(`/api/users/${id}`)
      .then(res => {
        if (!res.ok) reject(new Error('Not found'))
        return res.json()
      })
      .then(resolve)
      .catch(reject)
  })
}

// 체이닝
fetchUser(1)
  .then(user => fetchPosts(user.id))
  .then(posts => fetchComments(posts[0].id))
  .then(comments => console.log(comments))
  .catch(err => console.error(err))

async/await

async function loadData(userId) {
  try {
    const user = await fetchUser(userId)
    const posts = await fetchPosts(user.id)
    const comments = await fetchComments(posts[0].id)
    return comments
  } catch (error) {
    console.error('데이터 로딩 실패:', error)
    throw error
  }
}

병렬 처리

// 순차 실행 (느림)
const user = await fetchUser(1)
const settings = await fetchSettings(1)

// 병렬 실행 (빠름)
const [user, settings] = await Promise.all([
  fetchUser(1),
  fetchSettings(1),
])

Promise 유틸리티

메서드 설명
Promise.all 모두 완료될 때까지 대기, 하나라도 실패하면 reject
Promise.allSettled 모두 완료될 때까지 대기, 성공/실패 모두 반환
Promise.race 가장 먼저 완료된 결과 반환
Promise.any 가장 먼저 성공한 결과 반환

에러 처리 패턴

// 결과를 [error, data] 튜플로 반환하는 패턴
async function tryFetch(url) {
  try {
    const data = await fetch(url).then(r => r.json())
    return [null, data]
  } catch (error) {
    return [error, null]
  }
}

const [error, user] = await tryFetch('/api/user')
if (error) {
  console.error(error)
} else {
  console.log(user)
}

async/await는 Promise를 기반으로 하므로, Promise를 먼저 이해하는 것이 중요합니다.