Promise는 자바스크립트에서 비동기 작업을 보다 구조적으로 관리하기 위해 도입된 객체입니다. 자세히 살펴보면, 비동기 작업을 처리하기 위한 상태와 비동기 로직의 흐름을 제어하는 메서드 체인으로 구성됩니다. 여기에서 각 개념과 특징을 깊이 설명하겠습니다.
1. Promise의 정의와 역할
Promise는 비동기 작업의 현재 상태를 표현하고, 작업이 완료되었을 때 (성공 또는 실패) 처리할 로직을 연결할 수 있는 객체입니다. 콜백 방식과 달리, Promise를 사용하면 가독성을 유지하면서 명확하게 작업 흐름을 제어할 수 있습니다.
콜백 방식의 문제점
// 콜백 기반의 비동기 작업
function getData(callback) {
setTimeout(() => {
callback(null, "데이터 가져옴");
}, 1000);
}
getData((error, result) => {
if (error) {
console.error(error);
} else {
console.log(result);
}
});
위와 같은 코드는 콜백이 중첩되면서 복잡해지는 콜백 헬(Callback Hell)을 야기합니다.
Promise를 사용한 해결
Promise를 활용하면 중첩된 콜백 구조를 메서드 체인으로 단순화할 수 있습니다.
2. Promise의 상태
Promise는 불변 상태를 가지고 있어 다음 단계를 명확히 구분할 수 있습니다:
- Pending: 비동기 작업이 진행 중이며 아직 결과가 없는 상태.
- Fulfilled: 작업이 성공적으로 완료되어 결과 값을 얻은 상태.
- Rejected: 작업이 실패하거나 에러가 발생한 상태.
Promise는 항상 Pending에서 시작하며, 작업 완료 시 Fulfilled 또는 Rejected 상태로 전환되며 한 번 변하면 더 이상 변경되지 않습니다(불변성).
3. Promise의 구조
Promise는 생성자로 만들며, 내부적으로 두 개의 콜백 함수를 받습니다:
- resolve: 작업이 성공했을 때 호출.
- reject: 작업이 실패했을 때 호출.
특징 | resolve | reject |
상태 변경 | Promise를 Fulfilled 상태로 바꿈 | Promise를 Rejected 상태로 바꿈 |
전달 값 | 작업이 성공했을 때 결과 값을 전달 | 작업이 실패했을 때 에러 이유를 전달 |
연결 메서드 | .then() 메서드에서 결과 처리 | .catch() 메서드에서 에러 처리 |
예제: 간단한 Promise 생성
const myPromise = new Promise((resolve, reject) => {
const success = true; // 작업 성공 여부
if (success) {
resolve("작업이 성공했습니다!");
} else {
reject("작업이 실패했습니다.");
}
});
myPromise
.then(result => {
console.log(result); // "작업이 성공했습니다!" 출력
})
.catch(error => {
console.error(error); // 실패 시 에러 메시지 출력
});
4. Promise의 메서드
Promise 객체는 비동기 작업의 상태를 관리하고 후속 작업을 처리하기 위한 다양한 메서드를 제공합니다.
4.1 then
Promise가 성공했을 때 실행할 콜백을 연결합니다.
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("성공적으로 완료!"), 1000);
});
promise.then(result => {
console.log(result); // 출력: "성공적으로 완료!"
});
4.2 catch
Promise가 실패했을 때 실행할 콜백을 연결합니다.
const promise = new Promise((resolve, reject) => {
setTimeout(() => reject("작업 실패!"), 1000);
});
promise.catch(error => {
console.error(error); // 출력: "작업 실패!"
});
4.3 finally
성공 또는 실패 여부와 관계없이 항상 실행되는 코드를 연결합니다.
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve("완료!"), 1000);
});
promise
.then(result => console.log(result))
.finally(() => console.log("Promise가 종료되었습니다."));
5. Promise의 활용 사례
Promise는 주로 비동기 API 호출, 파일 읽기/쓰기, 타이머 등을 처리하는 데 사용됩니다.
예제: 비동기 API 호출
function fetchData() {
return new Promise((resolve, reject) => {
const success = true; // 가상의 성공 여부
setTimeout(() => {
if (success) {
resolve("데이터를 성공적으로 가져왔습니다!");
} else {
reject("데이터 가져오기 실패!");
}
}, 2000); // 2초 후 실행
});
}
// 사용 예제
fetchData()
.then(data => console.log(data))
.catch(error => console.error(error));
6. Promise의 병렬 처리
여러 개의 비동기 작업을 동시에 처리할 때는 Promise.all 또는 Promise.race를 사용할 수 있습니다.
Promise.all: 모든 작업이 완료되면 결과를 배열로 반환합니다.
const promise1 = new Promise(resolve => setTimeout(() => resolve("첫 번째 완료"), 1000));
const promise2 = new Promise(resolve => setTimeout(() => resolve("두 번째 완료"), 2000));
Promise.all([promise1, promise2]).then(results => {
console.log(results); // ["첫 번째 완료", "두 번째 완료"]
});
Promise.race: 가장 먼저 완료된 작업의 결과를 반환합니다.
const promise1 = new Promise(resolve => setTimeout(() => resolve("첫 번째 완료"), 1000));
const promise2 = new Promise(resolve => setTimeout(() => resolve("두 번째 완료"), 2000));
Promise.race([promise1, promise2]).then(result => {
console.log(result); // "첫 번째 완료"
});
7. Promise를 왜 사용하는가?
Promise는 비동기 작업 처리에서 다음과 같은 이점을 제공합니다:
- 가독성 향상: 콜백 헬을 피하고 코드를 체인 방식으로 구성.
- 에러 처리 통합: 모든 에러를 catch에서 관리 가능.
- 병렬 처리 가능: 여러 작업을 동시에 수행할 수 있는 유연한 메커니즘.
Promise는 자바스크립트에서 비동기 작업을 효율적으로 처리하는 핵심적인 도구입니다.
'프로그래밍 > javascript' 카테고리의 다른 글
즉시 실행 함수(IIFE, Immediately Invoked Function Expression) (0) | 2025.04.18 |
---|---|
노출 모듈 패턴(Revealing Module Pattern) (0) | 2025.04.18 |
고차 함수(Higher-Order Function) (0) | 2025.04.14 |
패키지 관리 도구 정리 및 비교 (npm / npx / yarn / pnpm / bower) (0) | 2025.04.11 |
자바스크립트 동등 연산자 (0) | 2025.04.11 |