0. 들어가면서
비동기 프로그래밍은 현대 웹 개발에서 필수적인 개념입니다. 얼마 전 포스팅에서도 뉴스 리스트 페이지를 개발하며 마주쳤던 문제인 비동기 제어 처리를 하는 법에 대해 포스팅 했지만 이번엔 온전히 그 개념만을 살펴보도록 하겠습니다. JavaScript에서 비동기 처리를 다루는 대표적인 방식으로 Promise와 async/await.
이번 포스팅에서는 이 두 개념을 비교하고, 어떻게 활용하는 것이 좋은지 알아보겠습니다.
1. Promise란?
Promise는 비동기 작업을 처리할 때 사용하는 JavaScript 객체로, 성공 또는 실패 상태를 갖습니다.
✅ Promise의 특징
- 대기(pending) → 성공(fulfilled) → 실패(rejected) 의 3가지 상태를 가짐
- .then(), .catch(), .finally()를 사용하여 결과를 처리 가능
- 콜백 지옥(Callback Hell)을 해결하기 위한 대안
📌 Promise 예제
const fetchData = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("데이터 로드 완료");
}, 2000);
});
};
fetchData()
.then(data => console.log(data))
.catch(err => console.log("에러 발생:", err));
이 코드는 fetchData() 함수가 2초 후 데이터를 반환하도록 만들었습니다.
.then()을 통해 성공한 경우 데이터를 받아 처리하고, .catch()를 통해 에러를 처리합니다.
2. async/await란?
async/await은 Promise를 기반으로 한 비동기 코드 처리 방식으로, 더욱 직관적이고 가독성이 좋습니다.
✅ async/await의 특징
- async 함수는 항상 Promise를 반환
- await 키워드는 Promise가 처리될 때까지 기다림
- try...catch 문을 사용해 에러 처리가 가능
📌 async/await 예제
const fetchData = async () => {
try {
const result = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const data = await result.json();
console.log(data);
} catch (error) {
console.log("에러 발생:", error);
}
};
fetchData();
위 코드에서는 await을 사용하여 데이터를 가져오는 동안 기다리도록 만들었습니다. 이 방식은 then/catch 체이닝보다 훨씬 간결하고 가독성이 좋습니다.
3. Promise vs async/await 비교
비교 항목Promiseasync/await
| 비교 항목 | Promise | async/await |
| 가독성 | .then() 체이닝으로 다소 복잡 | 동기 코드처럼 간결하게 작성 가능 |
| 에러 처리 | .catch() 체이닝 필요 | try...catch 블록 사용 |
| 실행 방식 | 비동기 방식 유지 | await을 사용하여 동기처럼 동작 |
| 병렬 실행 | Promise.all()을 활용해야 함 | Promise.all()과 함께 사용 가능 |
📌 Promise vs async/await 비교 예제
1) Promise 사용
fetchData()
.then(data => console.log(data))
.catch(error => console.log(error));
2) async/await 사용
async function getData() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.log(error);
}
}
4. 여러 개의 비동기 작업을 병렬로 실행하는 방법
여러 개의 비동기 작업을 동시에 실행하려면 Promise.all()을 사용하면 됩니다.
📌 Promise.all() 예제 (모든 요청 성공 시 결과 반환)
const fetchData1 = fetch("https://jsonplaceholder.typicode.com/todos/1").then(res => res.json());
const fetchData2 = fetch("https://jsonplaceholder.typicode.com/todos/2").then(res => res.json());
Promise.all([fetchData1, fetchData2])
.then(results => console.log(results))
.catch(error => console.log("에러 발생:", error));
Promise.all()을 사용하면 두 개의 요청을 병렬로 처리하여 속도를 최적화할 수 있습니다.
5. 언제 Promise를 사용하고 언제 async/await을 사용할까?
| 상황 | 추천 방식 |
| 간단한 비동기 처리 | async/await 사용 |
| 가독성이 중요한 경우 | async/await 사용 |
| 여러 개의 비동기 작업 병렬 실행 | Promise.all() 사용 |
| 에러를 세밀하게 제어해야 할 경우 | Promise 체이닝 활용 |
👉 결론:
단순한 비동기 처리는 async/await을 사용하고,
여러 개의 비동기 작업을 병렬로 처리할 경우 Promise.all()을 활용하는 것이 최적의 방법입니다.
6. 🔥면접 대비 예상 질문
Q1. Promise와 async/await의 차이점은?
✅ 답변:
Promise는 .then() 체이닝을 이용한 비동기 처리 방식이고, async/await은 await 키워드를 사용하여 동기 코드처럼 비동기 코드를 작성할 수 있습니다.
- Promise: .then(), .catch() 체이닝 방식 → 콜백 지옥 해결
- async/await: 동기적 코드 스타일로 가독성 향상
🔹 비교 예제
// Promise 사용
fetchData().then(data => {
console.log(data);
}).catch(error => {
console.log(error);
});
// async/await 사용
async function getData() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.log(error);
}
}
Q2. async/await 내부에서 에러 처리는 어떻게 하나요?
✅ 답변:
try...catch 블록을 사용하여 에러를 처리합니다.
🔹 예제
const fetchData = async () => {
try {
const response = await fetch("https://invalid-url.com"); // 잘못된 URL
const data = await response.json();
console.log(data);
} catch (error) {
console.error("에러 발생:", error);
}
};
fetchData();
try 블록에서 비동기 코드 실행 → catch 블록에서 에러 처리
Q3. async 함수는 항상 Promise를 반환하나요?
✅ 답변:
네, async 함수는 항상 Promise를 반환합니다.
- 함수 내부에서 값이 반환되면 자동으로 Promise로 감싸짐
🔹 예제
async function returnString() {
return "Hello";
}
returnString().then(console.log); // Promise를 반환하므로 .then() 사용 가능
Q4. 여러 개의 비동기 작업을 병렬로 실행하려면?
✅ 답변:
Promise.all() 또는 Promise.allSettled()을 사용하면 여러 개의 비동기 작업을 병렬 실행할 수 있습니다.
🔹 Promise.all() 예제 (모든 요청이 성공해야만 결과 반환)
const fetchData1 = fetch("https://jsonplaceholder.typicode.com/todos/1").then(res => res.json());
const fetchData2 = fetch("https://jsonplaceholder.typicode.com/todos/2").then(res => res.json());
Promise.all([fetchData1, fetchData2])
.then(results => console.log(results))
.catch(error => console.log("에러 발생:", error));
🔹 Promise.allSettled() 예제 (개별 요청의 성공/실패 여부를 반환)
Promise.allSettled([fetchData1, fetchData2])
.then(results => console.log(results)); // 성공/실패 여부를 각각 확인 가능
Q5. Promise와 async/await 중 어느 것을 선택해야 할까요?
✅ 답변:
- 가독성이 중요한 경우 → async/await
- 여러 개의 비동기 작업을 병렬 처리해야 할 경우 → Promise.all()
- 에러 처리를 세밀하게 제어해야 할 경우 → Promise의 .catch() 체이닝
'React' 카테고리의 다른 글
| [JavaScript]🔍화살표 함수(Arrow Function) vs function 키워드 차이점 (0) | 2025.04.11 |
|---|---|
| [React]🔑배열의 index를 key로 사용하면 안되는 이유 (0) | 2025.04.11 |
| [React]📘2. Virtual DOM(가상 돔)이란? (0) | 2025.04.02 |
| [React] 📝async/await + useEffect 내 순차 실행하기(비동기 제어 처리) (1) | 2025.03.24 |
| [React] 💻 모바일 웹 반응형 디자인 하기 (4) | 2024.12.28 |