Promise

ming0·2022년 6월 27일
0
post-thumbnail

자바스크립트는 비동기 처리를 위한 하나의 패턴으로 콜백 함수를 사용한다.
하지만 콜백 패턴은 콜백 헬로 인해 가독성이 나쁘고 비동기 처리 중 발생한 에러의 처리가 곤란하며 여러 개의 비동기 처리를 한번에 처리하는 데도 한계가 있다. (유지보수가 어렵다.)
👉 ES6에서는 비동기 처리를 위한 또 다른 패턴으로 프로미스(Promise)를 도입했다. 프로미스는 콜백 패턴이 가진 단점을 보완하며 비동기 처리 시점을 명확하게 표현 할 수 있다는 장점이 있다.


Promise

pending(대기)를 거쳐 콜백함수를 다시 부르겠다는 뜻
응답에 관한 정보를 갖고 있고 then, catch를 통해 결과 값을 처리한다.
맛집(식당)과 손님을 연결해주는 웨이팅 알리미어플 같은 존재
맛집(식당) - [제작 코드] / 손님 - [소비 코드] / 웨이팅 알리미어플 - [프로미스]

const promise = new Promise((resolve, reject) => {
  console.log("1번손님 들어오세요");
});

new Promise에 전달되는 함수를 executor(실행자, 실행 함수)라고 한다.
executor의 인수는 reslove, reject가 있으며 둘 중 한가지는 반드시 호출해야 한다.

  • resolve - 일이 성공적으로 끝난 경우 value와 함께 호출
  • reject - 에러 발생 시 에러 객체를 나타내는 error와 함께 호출

promise의 상태

pending(대기상태) - resolve(해결) - fulfilled(성공)
pending(대기상태) - reject(거부) - rejected(실패)

fulfilled 또는 rejected 상태를 settled 상태라고 한다.
settled상태는 fulfilled 또는 rejected 상태와 상관없이 pending이 아닌 상태로 비동기 처리가 수행된 상태를 말한다.
프로미스는 pending상태에서 settled상태(fulfilled 또는 rejected)로 변화할 수 있지만, settled상태가 되면 더는 다른 상태로 변화할 수 없다.


프로미스는 비동기 처리 상태와 함께 비동기 처리 결과(result)도 상태로 가진다.

후속 처리 메서드(then, catch, finally)

executor

  • new Promise가 만들어질 때 자동으로 실행된다. 결과를 최종적으로 만들어내는 제작코드를 포함한다.
    (맛집이 executor)

then, catch, finally

  • 제작 코드의 결과를 기다렸다가 이를 소비한다.
    (알리미어플에 번호를 등록하는 역할)

then

//제작코드
const promise = new Promise((resolve, reject) => {
  setTimeout(() =>{
    resolve('입장해주세요');
  }, 3000);
});

//소비코드
promise.then(value => {
  console.log(value);
});

// 3초 후에 입장해주세요 값 출력

  • then은 프로미스가 정상적으로 잘 수행이 되어서 마지막에 최종적으로 resolve라는 콜백 함수를 통해 전달한 값이 value의 파라미터로 전달되어서 들어온다.
//제작코드
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('손님의 입장순서가 아닙니다.'));
  }, 3000);
});

//소비코드
promise.then(value => {
  console.log(value);
});

// 3초 후에 Uncaught Error : 손님의 입장순서가 아닙니다. 에러 메세지 출력

  • then은 성공적인 케이스만 다루기 때문에 reject를 쓰게 되면 잡히지 않는 에러가 발생한다.

catch

방금 위에 예시와 같은 에러가 발생한 경우만 다루고 싶을 때는 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)

finally

성공이든 실패든 상관없이 무조건 마지막에 호출되는 메서드이다.

//제작코드
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

0개의 댓글