Promise 생성자 함수를 new 연산자와 함께 호출하면 프로미스(Promise 객체)를 생성한다. … Promise 생성자 함수는 비동기 처리를 수행할 콜백 함수를 인수로 전달받는데, 이 콜백 함수는 resolve와 reject 함수를 인수로 전달받는다.
프로미스 객체의 구성
| 구성 요소 | 설명 |
|---|---|
[[PromiseState]] |
pending, fulfilled, rejected 중 하나의 상태 (내부 슬롯, 직접 접근 불가) |
[[PromiseResult]] |
성공 시 결과 값, 실패 시 오류 객체 (내부 슬롯, 직접 접근 불가) |
then, catch, finally |
후속 처리 메서드. 전부 새로운 Promise 객체 반환함 |
{
[[PromiseState]]: "pending" | "fulfilled" | "rejected",
[[PromiseResult]]: any, // 성공 시 결과 or 실패 시 에러
then(onFulfilled, onRejected),
catch(onRejected),
finally(onFinally)
}
const fulfilled = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) resolve(1);
else reject(2);
}, 1000);
})
.then((res) => console.log(res)) // 건너뜀
.catch((err) => console.error(err)); // 콘솔에러 2
프로미스의 비동기 처리 상태가 변화하면 위와 같이 이에 따른 후속 처리를 해야 한다.
그때 프로미스 후속 메서드 then, catch, finally를 사용하며, 후속 처리 메서드는 프로미스를 반환하고 비동기로 동작한다.
then에서 값을 리턴하면 그 값은 다음 then 인자로 들어감
만약 then 안에서 다시 비동기 작업(Promise)을 리턴하면 다음 then은 그 비동기 작업이 끝난 뒤에 실행됨.
// 초기 Promise 생성
const p = new Promise((resolve) => resolve(10));
// 후속 처리 (새로운 Promise 반환)
p
.then((res) => res + 1) // → Promise (resolved with 11)
.catch((err) => console.log(err)) // → Promise (그대로 통과)
.finally(() => console.log("done")); // → Promise (상태 유지)
프로미스의 비동기 처리 상태에 따라 후속 처리 메서드에 인수로 전달한 콜백 함수가 선택적으로 호출된다.
참고로, then 메서드가 2개의 콜백 함수를 받아서 에러 처리까지 할 수도 있다. 첫 번째 콜백 함수는 비동기 처리가 성공했을 때 호출 되는 성공 처리 콜백 함수, 두 번째 콜백 함수는 비동기 처리가 실패했을 때 호출되는 실패 처리 콜백 함수. 그러나 보통은 위와 같이 then, catch 각각을 하는 경우가 많다.
아무튼 한 번 프로미스는 영원히 프로미스라서, 계속해서 .then, .catch, .then, .finally를 태울 수 있다.
const prom = (val) =>
new Promise((resolve, reject) => {
setTimeout(() => {
if (val > 0.5) resolve(1);
else reject(2); // 호출됨.
}, 1000);
})
.then((res) => console.log(res)) // 건너뜀
.finally(() => console.log("finally")) // 콘솔: finally
.then(() => console.log("then")) // 건너뜀
.catch((err) => console.error(err)) // 콘솔에러: 2
.then((res) => console.log(res)) // **(catch 이후엔 then만 태움)**콘솔: undefined
.catch((err) => console.error(err)); // 건너뜀
prom(0.3);