Ryu.log

[ NodeJS 05 ] 프로미스(Promise) 이해하기 본문

Prev-content

[ NodeJS 05 ] 프로미스(Promise) 이해하기

류뚝딱 2018. 7. 25. 11:51


1. Promise 이해하기

Promise가 무엇인지 한번 찢어보자...!!

먼저 크롬 개발자 도구에서 Promise를 한번 쳐보자!



Promise라는 함수가 존재한다, 사실 함수라기 보다는 앞글자가 대문자면 생성자라는 의미이다. 

그래서 함수의 앞에 new를 붙힐 수 있고, 아래 코드와 같은 구조로 Promise는 구성되어 있다.

new Promise((resolve, reject) => {
  // 이곳에 코딩...
})

Promise는 위 코드와 같은 방식으로, 앞쪽에 new를 붙혀서 new Promise를 해주고, 

생성자의 첫번재 인자로 resolvereject가 매개변수인 함수를 넣어준다. 이 구조는 그냥 외우면 된다.


resolve - 성공 메시지

reject   - 실패 메시지


그 뒤에 안쪽에서 코딩을 아래와 같이 진행한다.

new Promise((resolve, reject) => { const a = 1; const b = 2; if (a + b > 2) { resolve( a + b ); // 성공메시지 }else{ reject( a + b ); // 실패메시지 } })

위와 같이 new Promise(껍데기)를 만들어준 뒤에 안쪽에 원하는 코딩을 진행한다.

위와같이 값을비교하여 성공, 실패 를 구분하는 예제 코드를 작성한 뒤에 변수에 담아준다.

const plus = new Promise((resolve, reject) => { const a = 1; const b = 2; if (a + b > 2) { resolve( a + b ); // 성공메시지 }else{ reject( a + b ); // 실패메시지 } })

이렇게 Promise를 변수 담아 준 뒤에, 이전에 챕터에서 한번 언급되었던 than과 catch를 사용 해보자.


위 코드에서 resolve는 성공메시지 reject는 실패메시지라고 했다.

변수 plus에 담긴 Promise안쪽 조건문을 보자, a + b 는 3이고 2보다 크기 때문에 resolve가 실행된다.


아래 코드를 보자.

plus
  .then((success) => {
    console.log(success);
  })
  .catch((fail) => {
    console.error(fail);
  });

Promise에서 


resolve가 실행되면 then으로 빠져서 성공 메세지가 출력되고, 

reject가 실행되면 catch로 빠져서 애러 메세지가 출력된다.



resolve(msg) -> then ((msg)

reject(err)     -> catch((err)



그렇다면 이번에는 반대로 Promise안에 조건문을 실패로 만들어 reject가 실행되게 해보자.

const plus = new Promise((resolve, reject) => { const a = 1; const b = 2; if (a + b < 2) { resolve( a + b ); // 성공메시지 }else{ reject( a + b ); // 실패메시지 } }) plus .then((success) => { console.log(success); }) .catch((fail) => { console.error(fail); })

조건문의 조건을 변경하여 a + b의 합이 2보다 작아야 true가 되게 만들었다, 위 조건문은 else로 빠져서 reject가 실행되고

reject는 catch로 빠져서 console.error를 출력할 것이다.



이전 챕터에서 콜백과 프로미스를 비교하면서 Users.findOne , Users.update , Users.remove이런 함수들을 설명하며 then과 catch를 사용했는데,

지금은 갑자기 new Promise를 하고 resolve, reject이런것들이 나오는게 이상할 것이다. 


이유는 예시로 만든 함수 Users.findOne , Users.update , Users.remove안쪽에 Promise를 선언해놓아서 동작 하도록 만들었기 때문이다,

아래 코드를 보자.

const Users = {
  findOne() {
    return new Promise ((resolve, reject) => {
      if ('사용자를 찾았으면'){
        resolve('사용자');
      }else{
        reject('못 찾았어요');
      }
    })
  },
  remove () { return new Promise () ...},
  update () { return new Promise () ...}
}
User.findOne();

이런식으로 함수내부적으로 new Promisereturn하기 때문에,

Users.findOne , Users.update , Users.remove에서 then과 catch를 사용할 수 있는 것이다.


이번에는 비슷한 다른예제의 코드를 한번 살펴보자

const condition = true; // true면 resolve, false면 reject
const promise = new Promise((resolve, reject) => {
  if(condition) {
    resolve('성공');
  }else{
    reject('실패');
  }
});

promise
  .then((message) => {
     console.log(message);  // 성공 (resolve)한 경우 실행
  })
  .catch((error) => {
    console.error(error);
  });

이전 코드와 별반 다른게 없지만, 한번 더 익숙해지도록 코드를 살펴보고 넘어가자


이번에는 위코드에서 then이 연달아서 나오는 경우의 코드를 한번보자

promise
  .then((message) => {
    return new Promise((resolve, reject) => {
      resolve(message);    
    });
  })
  .then((message2) => {
    console.log(message2);
    return new Promise((resolve, reject) => {
      resolve(message2);
    })
  })
  .then((message3) => {
    console.log(message3);
  })
  .catch((error) => {
    console.error(error);
  })

이게 바로 Promise가 좋은점이다, 만약 이런상황을 콜백으로 했다면 콜백지옥이 발생하여 암에 걸리거나 난독증이 생길것이다.

이렇게 new Promisereturn해주면, 계속해서 다음 then으로 계속해서 이어진다.


현재 모두 바로 resolve하도록 코드가 작성되었는데,

만약 첫번째 Promise에서(4번라인) resolve가 아니라 reject가 된다면 곧장 아래쪽 then은 무시되고 catch로 이어진다.

마찬가지로 두번째 Promise에서(9번 라인) resolve가 아니라 reject가 된다면 9번 줄 아래쪽 then은 무시되고 catch로 바로 이어질 것이다.


예시로 첫번째 thenresolve를 하고 두번째 then에서는 reject를 해보자. 아래와 같은 결과가 나올것이다.


Comments