이번에는 Promise 객체에 대해 살펴보고, 비동기 작업을 처리하는데 있어서 실제 예제를 통해 Promise의 생성, 사용, 체이닝 등 프로미스를 효율적으로 활용하는 여러 방법에 대해 정리해 보겠습니다.

자바스크립트 Promise
Promise는 자바스크립트에서 비동기 작업을 처리하는 객체입니다. '비동기 작업'이란 시간이 걸리는 작업을 말하며, 이 작업이 완료될 때까지 다른 코드의 실행을 멈추지 않고 계속 진행할 수 있게 해줍니다.
Promise는 다음 세 가지 상태 중 하나를 가집니다.
- 대기(Pending): 초기 상태, 비동기 작업이 아직 완료되지 않음
- 이행(Fulfilled): 작업이 성공적으로 완료됨
- 거부(Rejected): 작업이 실패함
Promise를 사용하면 비동기 작업의 결과를 처리하는 코드를 더 쉽게 작성할 수 있습니다.
Promise 만들기
Promise 객체는 다음과 같이 생성합니다:
const myPromise = new Promise((resolve, reject) => {
// 비동기 작업을 여기에 작성합니다
// 작업이 성공하면 resolve를 호출하고,
// 실패하면 reject를 호출합니다
});
여기서 resolve
와 reject
는 함수입니다. resolve
는 Promise가 성공적으로 완료되었을 때 호출하고, reject
는 실패했을 때 호출합니다.
예를 들어, 5초 후에 무작위로 성공 또는 실패하는 Promise를 만들어 보겠습니다:
const randomPromise = new Promise((resolve, reject) => {
console.log("Promise 시작: 5초 후에 결과가 나옵니다.");
setTimeout(() => {
const randomNumber = Math.random();
if (randomNumber > 0.5) {
resolve("성공! 숫자는 " + randomNumber + "입니다.");
} else {
reject("실패! 숫자는 " + randomNumber + "입니다.");
}
}, 5000);
});
console.log("Promise를 생성했습니다. 결과를 기다리는 중...");
randomPromise
.then((result) => {
console.log("Promise 성공:", result);
})
.catch((error) => {
console.log("Promise 실패:", error);
});
console.log("이 메시지는 Promise 결과와 상관없이 바로 출력됩니다.");
이 예제를 실행하면 다음과 같은 순서로 콘솔에 출력됩니다.
- "Promise 시작: 5초 후에 결과가 나옵니다."
- "Promise를 생성했습니다. 결과를 기다리는 중..."
- "이 메시지는 Promise 결과와 상관없이 바로 출력됩니다."
- (5초 후) "Promise 성공: 성공! 숫자는 X입니다." 또는 "Promise 실패: 실패! 숫자는 X입니다."
이 예제에서 볼 수 있듯이, Promise를 사용하면 비동기 작업의 결과를 기다리는 동안 다른 코드를 실행할 수 있습니다.
Promise 사용하기
Promise를 사용할 때는 주로 다음 메서드를 활용합니다.
then()
then()
메서드는 Promise가 성공적으로 완료되었을 때 실행될 콜백 함수를 등록합니다.
myPromise.then((result) => {
console.log("성공:", result);
});
catch()
catch()
메서드는 Promise가 실패했을 때 실행될 콜백 함수를 등록합니다.
myPromise.catch((error) => {
console.log("실패:", error);
});
finally()
finally()
메서드는 Promise가 성공하든 실패하든 상관없이 항상 실행될 콜백 함수를 등록합니다.
myPromise.finally(() => {
console.log("Promise 작업이 완료되었습니다.");
});
이 세 메서드를 모두 사용한 예제입니다.
function fetchData(shouldSucceed) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldSucceed) {
resolve("데이터를 성공적으로 가져왔습니다.");
} else {
reject("데이터 가져오기에 실패했습니다.");
}
}, 2000);
});
}
console.log("데이터 요청을 시작합니다...");
fetchData(true) // true를 false로 바꿔보세요
.then((result) => {
console.log("성공:", result);
})
.catch((error) => {
console.log("실패:", error);
})
.finally(() => {
console.log("데이터 요청 작업이 완료되었습니다.");
});
console.log("데이터 요청이 진행 중입니다.");
이 예제를 실행하면 다음과 같은 순서로 출력됩니다.
- "데이터 요청을 시작합니다..."
- "데이터 요청이 진행 중입니다."
- (2초 후) "성공: 데이터를 성공적으로 가져왔습니다." 또는 "실패: 데이터 가져오기에 실패했습니다."
- "데이터 요청 작업이 완료되었습니다."
fetchData
함수에 전달하는 인자를 false
로 바꾸면 실패 케이스를 볼 수 있습니다.
Promise 체이닝
Promise의 강력한 기능 중 하나는 여러 개의 비동기 작업을 연속적으로 처리할 수 있다는 것입니다. 이를 'Promise 체이닝'이라고 합니다.
각 then()
메서드는 새로운 Promise를 반환하므로, 이를 이용해 여러 작업을 연결할 수 있습니다.
function fetchUserData(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (userId === 1) {
resolve({ id: 1, name: "김철수" });
} else {
reject("사용자를 찾을 수 없습니다.");
}
}, 1000);
});
}
function fetchUserPosts(userName) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (userName === "김철수") {
resolve(["안녕하세요", "반갑습니다"]);
} else {
reject("게시물을 가져올 수 없습니다.");
}
}, 1000);
});
}
console.log("사용자 데이터와 게시물을 가져오는 중...");
fetchUserData(1)
.then((user) => {
console.log("사용자 정보:", user);
return fetchUserPosts(user.name);
})
.then((posts) => {
console.log("사용자의 게시물:", posts);
})
.catch((error) => {
console.log("오류 발생:", error);
})
.finally(() => {
console.log("모든 작업이 완료되었습니다.");
});
console.log("데이터 요청이 진행 중입니다.");
이를 실행하면 다음과 같은 순서로 출력됩니다.
- "사용자 데이터와 게시물을 가져오는 중..."
- "데이터 요청이 진행 중입니다."
- (1초 후) "사용자 정보: { id: 1, name: '김철수' }"
- (추가 1초 후) "사용자의 게시물: ['안녕하세요', '반갑습니다']"
- "모든 작업이 완료되었습니다."
이 예제에서는 첫 번째 Promise(fetchUserData
)가 완료된 후, 그 결과를 이용해 두 번째 Promise(fetchUserPosts
)를 실행합니다. 이렇게 여러 비동기 작업을 순차적으로 처리할 수 있습니다.
Promise.all()
여러 개의 Promise를 동시에 실행하고 모든 Promise가 완료될 때까지 기다리려면 Promise.all()
을 사용합니다.
function fetchData(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (id <= 3) {
resolve(`데이터 ${id}`);
} else {
reject(`ID ${id}에 해당하는 데이터가 없습니다.`);
}
}, 1000);
});
}
console.log("여러 개의 데이터를 동시에 가져오는 중...");
Promise.all([
fetchData(1),
fetchData(2),
fetchData(3)
])
.then((results) => {
console.log("모든 데이터를 성공적으로 가져왔습니다:", results);
})
.catch((error) => {
console.log("데이터 가져오기 실패:", error);
});
console.log("데이터 요청들이 진행 중입니다.");
이 예제를 실행하면 다음과 같은 순서로 출력됩니다.
- "여러 개의 데이터를 동시에 가져오는 중..."
- "데이터 요청들이 진행 중입니다."
- (약 1초 후) "모든 데이터를 성공적으로 가져왔습니다: ['데이터 1', '데이터 2', '데이터 3']"
Promise.all()
은 배열 내의 모든 Promise가 성공적으로 완료되었을 때만 결과를 반환합니다. 만약 하나라도 실패하면 즉시 실패로 처리됩니다.
'프로그래밍 언어 > JavaScript' 카테고리의 다른 글
자바스크립트 네트워크 Fetch API와 비동기 처리 가이드 - 자바스크립트 #11 (0) | 2024.07.26 |
---|---|
AJAX를 사용한 비동기 JavaScript와 서버 통신, AJAX의 작동 원리와 예제 - 자바스크립트 #10 (0) | 2024.07.24 |
자바스크립트 DOM 이해하기. DOM 트리, 요소 조작, 이벤트 리스너 - 자바스크립트 #9 (0) | 2024.07.22 |
자바스크립트 이벤트 객체와 리스너 addEventListener 활용법 - 자바스크립트 #8 (0) | 2024.07.19 |
자바스크립트 배열 기초와 활용. 배열 메서드와 다차원 배열 - 자바스크립트 #7 (0) | 2024.07.16 |