Promise란?
JavaScript에서 네트워크 요청이나 파일 읽기처럼 시간이 걸리는 작업은 비동기로 처리합니다. Promise는 이러한 비동기 작업의 최종 완료 또는 실패를 나타내는 객체입니다.
비동기
비동기(asynchronous)는 작업의 결과를 기다리지 않고 다음 코드를 먼저 실행하는 방식입니다. 서버에 데이터를 요청하거나 파일을 읽는 동안 프로그램이 멈춰 있지 않고 다른 일을 계속할 수 있습니다.
문제는 결과가 언제 도착하는지 알 수 없다는 점입니다. 이를 다루기 위해 예전에는 콜백 함수를 전달했지만, 콜백 안에 다시 콜백을 중첩하면 코드가 깊어지고 에러 처리가 흩어지는 문제가 있었습니다.
Promise
Promise는 “지금은 결과를 모르지만, 나중에 성공 값이나 실패 이유 중 하나를 돌려주겠다”는 약속을 담은 객체입니다. Array나 Object처럼 JavaScript가 제공하는 독자적인 객체이며, 비동기 작업의 진행 상황을 다음 세 가지 상태로 표현합니다.
- Pending(대기): 아직 이행되지도 거부되지도 않은 초기 상태
- Fulfilled(이행): 비동기 연산이 성공적으로 완료되어 결과 값을 가진 상태
- Rejected(거부): 비동기 연산이 실패해 실패 이유를 가진 상태
한 번 이행 또는 거부 상태로 바뀌면 다시 다른 상태로 변하지 않습니다.
Pending(대기)
new Promise()로 생성한 직후의 상태입니다. 생성자에는 resolve와 reject를 인자로 받는 콜백 함수를 전달합니다.
const promise = new Promise(function (resolve, reject) {
// 비동기 작업 수행
});
이 콜백 안에서 작업이 성공하면 resolve(값)를, 실패하면 reject(이유)를 호출해 상태를 바꿉니다.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
const isSuccess = true;
if (isSuccess) {
resolve("데이터"); // Fulfilled 상태로 전환
} else {
reject(new Error("요청 실패")); // Rejected 상태로 전환
}
}, 1000);
});
Fulfilled(이행)
resolve가 호출되어 비동기 연산이 성공적으로 완료된 상태입니다. .then() 메서드로 전달된 결과 값을 받을 수 있습니다.
promise.then((data) => {
console.log(data); // "데이터"
console.log("이행 상태가 되면 처리 결과를 받아 후속 작업을 수행합니다.");
});
Rejected(거부)
reject가 호출되거나 처리 도중 에러가 발생해 연산이 실패한 상태입니다. .catch() 메서드로 실패 이유를 받아 후속 조치를 할 수 있습니다.
promise.catch((error) => {
console.log(error);
console.log("실패에 대한 후속 조치...");
});
메서드 체이닝
.then()과 .catch()는 다시 Promise를 반환하므로 여러 개를 이어서 연결할 수 있습니다. 콜백을 중첩하지 않고 위에서 아래로 읽히는 흐름으로 비동기 작업을 나열할 수 있습니다.
fetch("/api/user")
.then((response) => response.json())
.then((user) => {
console.log(user.name);
})
.catch((error) => {
console.log("요청 처리 중 오류가 발생했습니다.", error);
})
.finally(() => {
console.log("성공, 실패 여부와 관계없이 항상 실행됩니다.");
});
체인 중간에서 발생한 에러는 가장 가까운 .catch()로 전달되므로 에러 처리를 한곳에 모을 수 있습니다. .finally()는 결과와 상관없이 마지막에 실행되어 로딩 상태를 해제하는 것 같은 정리 작업에 사용합니다.
한 줄 요약
Promise는 비동기 작업의 완료 또는 실패를 나타내는 객체로, Pending → Fulfilled 또는 Rejected 중 하나의 상태로 한 번만 바뀌며 각각 .then()과 .catch()로 결과를 처리합니다.
참고