async/await 완벽 이해하기 – JavaScript 비동기 처리의 핵심
2025. 5. 28. 22:48ㆍFront-End/Vue.js
반응형
1. 왜 비동기 처리가 필요한가?
자바스크립트는 단일 스레드(single-thread) 기반 언어다.
즉, 어떤 작업이 오래 걸리면(예: 네트워크 요청), 그동안 다른 작업은 멈춰버리게 된다.
이를 해결하기 위해 자바스크립트는 비동기 처리 방식을 도입했는데,
그 대표적인 방식이 바로 Promise고, 그 위에 편하게 쓸 수 있도록 만들어진 문법이 async/await이다.
2. Promise 복습: 기본 비동기 구조
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("성공")
}, 1000)
})
}
getData()
.then(result => console.log(result)) // "성공"
.catch(error => console.error(error))
- Promise는 미래에 완료될 작업을 나타냄
- .then()으로 성공 결과를 받고
- .catch()로 실패를 처리
3. async/await: 동기 코드처럼 보이는 비동기
이걸 async/await로 바꾸면 이렇게 된다:
async function loadData() {
try {
const result = await getData()
console.log(result)
} catch (err) {
console.error('에러 발생:', err)
}
}
✅ 핵심 문법 정리
| 문법 | 의미 |
| async function | 비동기 함수 선언. 내부에서 await 사용 가능 |
| await | Promise가 끝날 때까지 기다림. 완료되면 결과 반환 |
| try/catch | 오류 발생 시 안전하게 핸들링 |
4. await의 동작 방식은 실제로 어떻게 되나?
await는 사실 내부적으로 .then()을 호출하는 것과 같다.
const result = await getData()
// ↔ 동일한 의미
getData().then(result => { ... })
단, await는 async 함수 안에서만 사용 가능하다는 점에 주의해야 한다.
// ❌ 오류 발생
const result = await getData()
5. 실전 예제 – API 호출
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`)
const data = await response.json()
return data
} catch (error) {
console.error("사용자 정보를 불러오는 데 실패:", error)
return null
}
}
여기서 중요한 건 두 번의 await이다.
- fetch()는 Promise를 반환
- .json()도 비동기이기 때문에 다시 await
6. 병렬 처리: await를 동시에 쓰면 직렬
// ❌ 느리다 – 순차 실행
const a = await fetchA()
const b = await fetchB()
✅ 병렬 처리하려면 Promise를 먼저 만들고, 나중에 await
const promiseA = fetchA()
const promiseB = fetchB()
const a = await promiseA
const b = await promiseB
또는 Promise.all()을 사용
const [a, b] = await Promise.all([fetchA(), fetchB()])
7. 에러 핸들링은 반드시 try/catch
await는 내부적으로 Promise.reject()가 발생하면 예외로 던져지기 때문에
꼭 try/catch로 감싸야 안전하다.
try {
const data = await fetchData()
} catch (error) {
// 네트워크 오류, 500 에러 등
}
에러 없이 쓰면 무중단으로 서비스가 죽을 수 있다.
8. Vue와 async/await
Vue의 onMounted()에서 비동기 호출할 때 자주 쓰는 패턴:
onMounted(async () => {
try {
const res = await fetch('/api/data')
data.value = await res.json()
} catch (e) {
console.error("데이터 로드 실패:", e)
}
})
또는 Composition 함수에서:
const loadSomething = async () => {
const result = await apiCall()
something.value = result
}
9. async/await의 한계
- await는 직렬 실행이 기본이기 때문에 무턱대고 사용하면 성능 저하 가능
- 오래 걸리는 작업은 Promise.all()로 병렬 처리 고려
- 반복문 안에서 await를 쓰면 → 순차 실행됨 (주의!)
마무리 정리
| 키우드 | 설명 |
| async | 비동기 함수 선언 |
| await | Promise의 완료를 기다림 |
| try/catch | 예외 처리 필수 |
| Promise.all | 병렬 처리에 적합 |
| Vue에서의 사용 | API 호출, 파일 업로드, 초기 데이터 로딩 등 |
반응형
'Front-End > Vue.js' 카테고리의 다른 글
| Vue Composition API - setup() 정리 기준 (1) | 2025.07.10 |
|---|---|
| Vue API 호출을 관리하는 구조 – async/await과 useXXX 패턴(컴포저블) (0) | 2025.05.28 |
| Vue Composition API를 쓰면서 헷갈리는 this, 화살표 함수, Promise, async/await 정리 (0) | 2025.05.28 |
| Vue 프로젝트 폴더 구조 정리 (0) | 2025.05.18 |
| Vue3 - Computed() (0) | 2025.04.06 |