자바스크립트는 비동기 처리를 위한 하나의 패턴으로 콜백 함수를 사용한다.
하지만 콜백 패턴은 콜백 헬로 인해 가독성이 나쁘고 비동기 처리 중 발생한 에러의 처리가 곤란하며 여러 개의 비동기 처리를 한번에 처리하는 데도 한계가 있다. (유지보수가 어렵다.)
👉 ES6에서는 비동기 처리를 위한 또 다른 패턴으로 프로미스(Promise)를 도입했다. 프로미스는 콜백 패턴이 가진 단점을 보완하며 비동기 처리 시점을 명확하게 표현 할 수 있다는 장점이 있다.
pending(대기)를 거쳐 콜백함수를 다시 부르겠다는 뜻
응답에 관한 정보를 갖고 있고 then, catch를 통해 결과 값을 처리한다.
맛집(식당)과 손님을 연결해주는 웨이팅 알리미어플 같은 존재
맛집(식당) - [제작 코드] / 손님 - [소비 코드] / 웨이팅 알리미어플 - [프로미스]
const promise = new Promise((resolve, reject) => {
console.log("1번손님 들어오세요");
});
new Promise에 전달되는 함수를 executor(실행자, 실행 함수)라고 한다.
executor의 인수는 reslove, reject가 있으며 둘 중 한가지는 반드시 호출해야 한다.
pending(대기상태) - resolve(해결) - fulfilled(성공)
pending(대기상태) - reject(거부) - rejected(실패)
fulfilled 또는 rejected 상태를 settled 상태라고 한다.
settled상태는 fulfilled 또는 rejected 상태와 상관없이 pending이 아닌 상태로 비동기 처리가 수행된 상태를 말한다.
프로미스는 pending상태에서 settled상태(fulfilled 또는 rejected)로 변화할 수 있지만, settled상태가 되면 더는 다른 상태로 변화할 수 없다.
프로미스는 비동기 처리 상태와 함께 비동기 처리 결과(result)도 상태로 가진다.
executor
then, catch, finally
//제작코드
const promise = new Promise((resolve, reject) => {
setTimeout(() =>{
resolve('입장해주세요');
}, 3000);
});
//소비코드
promise.then(value => {
console.log(value);
});
// 3초 후에 입장해주세요 값 출력
//제작코드
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('손님의 입장순서가 아닙니다.'));
}, 3000);
});
//소비코드
promise.then(value => {
console.log(value);
});
// 3초 후에 Uncaught Error : 손님의 입장순서가 아닙니다. 에러 메세지 출력
방금 위에 예시와 같은 에러가 발생한 경우만 다루고 싶을 때는 catch라는 메서드를 사용한다.
//제작코드
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('손님의 입장순서가 아닙니다'));
}, 3000)
});
//소비코드
promise
.then(value => {
console.log(value);
})
.catch(error => {
console.log(error);
});
// Error: 손님의 입장순서가 아닙니다
Uncaught와 같은 에러가 발생하지 않고, 받아온 에러가 콘솔 창에 실행된다.
프로미스에 then을 호출하게 되면 then은 결국 똑같은 프로미스를 리턴하기 때문에 리턴된 프로미스에 catch를 다시 호출할 수 있다. 👉 프로미스 체이닝(chaining)
성공이든 실패든 상관없이 무조건 마지막에 호출되는 메서드이다.
//제작코드
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('손님의 입장순서가 아닙니다'));
}, 3000)
});
//소비코드
promise
.then(value => {
console.log(value);
})
.catch(error => {
console.log(error);
})
.finally(() => {
console.log('-제주맛집');
});
[참고]
모던 자바스크립트 Deep Dive
알잘딱깔센 JavaScript