자바스크립트를 공부하다보면 Promise라는 말을 많이 듣는다.

 

직역하면 약속인건 대충 알겠는데 이게 함수인지 메서드인지 뭔지 정확히 모르는 사람들이 많다.

이번 글에서는 Promise가 뭔지 간단하게 알아볼 것이다.

 

 

간단한 예로 실행순서가 보장되어야하는 

서버에서 데이터를 받아와서 출력해야하는 상황을 가정해보자.

 

 

데이터 요청 > 데이터 수신 > 데이터 출력

 

 

이 세 가지 순서가 기본적으로 보장되어야 하지만 비동기로 운영되는 자바스크립트는

데이터를 요청해두고 수신되기전에 출력부터 해버리려고한다.

 

출력하는 입장에서는 당연히 데이터가 없는데 출력은 하라고하니 당황해서 에러를 뱉을 것이다.

그리하여 이런 경우는 동기적으로 운영하여 순서를 보장해주어야한다.

그러기 위해 사용되는 것이 Promise다.

 

 

 

Promise객체는 쉽게 말하면

언제 돌아올지 모르지만 돌아오면 알려주는 약속이다.

 

let p = new Promise(function(resolve, reject){
    console.log("promise 들어왔음!")
})
console.log(p);

 

어려운 말은 다 넘어가고 new Promise를 사용해 새로운 프로미스를 선언해주고

안에는 콜백함수를 하나 넘겨준다.

 

 

그리고 그 콜백함수안에는 두가지 파라미터를 넘겨주어야하는데 

첫번 째 파라미터로는 실행이 완료됨을 알리는 함수

두번 째 파라미터로는 실패했을때를 알리는 함수

 

 

 

우리가 배달의 민족으로 족발을 주문한다고 가정해보자.

우리가 메뉴를 고르고 주문을 넣는 순간 promise라는 주문이 이행된다.

 

 

 

그렇게 되면 족발집 사장님은 주문을 받을지

아니면 가게사정으로 주문을 취소시킬지를 정해야한다.

안그러면 가게에 "배달의민족 주문~"이라는 알람이 끊기지 않을 것이다.

 

 

 

위 코드에 대입하면 사장님이

주문을 받는다면 resolve("30분걸림") 이라는 코드를 작성할 것이고,

주문을 취소한다면 reject("주문취소")라는 코드를 작성할 것이다.

 

 

 

위 예시에서 정확히 말하면 주문취소도 의도한 상황이기에

resolve 내에서 분기해줘야하는 것이 맞지만

기본적인 개념을 쉽게 설명하기 위해 reject를 사용했다.

나중에 Promise를 완전히 이해하면 무슨 말인지 알 것이다.

 

 

 

이제 코드를 살펴보자.

 

 

2번라인에 현재 주문 가능한 음식 리스트가 있고,

3번라인에 내가 먹고싶은 메뉴가 적혀있다.

 

만약 내가 치킨을 주문 넣었다면 주문 가능한 음식이니 사장님은 아래처럼

"30분후 도착이라는 메시지와 함께 주문성공"을 표현할것이다.

 

 

 

 

그러나 반대로 없는 메뉴인 감자튀김을 주문한다면 

아래처럼 거절당한다.

 

 

Promise의 상태는 3가지가 있다.

pending - 요청을 날렸지만 아직  완료가 되지 않은 상태.
resolve - 요청을 날렸고 정상적으로 이행되었다고 답이 돌아온 상태.
reject - 요청을 날렸고 문제가 생겼다는 답이 돌아온 상태.

 

 

그래서 pending일때는 기다렸다가 resolve나 reject가 돌아오면 다음 프로세스를 태우는 식으로 코드를 작성한다.

 

 

 

const login = tryLogin.then(checkLogin).catch(showErrorMessage)

정리하면 위 코드 한줄로 표현하겠다.

 

로그인을 하려고한다.

로그인을 시도하는 Promise가 tryLogin이라는 함수고 이 함수는 아이디와 패스워드를 서버로 보낸다고 가정하자.

서버에서 로그인 성공,실패여부를 리턴해줄 것이고 리턴받으면 이제 성공이면 성공, 실패면 실패로 표현해줄 수 있다.

 

그러나 DB에러나 네트워크에러같은 문제가 발생하면 catch에서 잡아낸다.

 

 

 

 

 

 

Catch는 필수

 

아무래도 비동기 작업은 위험하다. 어떤 문제가 도사리고 있을지 모르기에 항상 보험을 깔아두자.

catch를 포함하지 않으면

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason

뭐 이런 오류가 반겨주는데 대충 비동기작업을 하는데 에러핸들링이 되지 않았다는 소리다.

 

 

 

다른 예제를 찾아보면 catch를 안써둔 코드들도 있는데 then의 두번째 인자로 넘겨주어도 동일한 효과다.

Promise.then(success()).catch(error())    ===  Promise.then(success(),error())

두 코드는 똑같다.

 

 

 

사실 Promise의 개념을 알아보기 위한 글이었지만 ES6에 비동기제어를 위한 Async가 도입되었다.

Async await도 결국 Promise기반이니 개념을 알아두면 좋을 듯 하다.

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기