코딩쌀롱

[JS] Promise 본문

개발공부

[JS] Promise

이브✱ 2021. 1. 26. 22:14

 

✱ Promise

const promise = new Promise((resolve, reject) => {...});

 new Promise()로 프로미스를 생성할 수 있으며, 그 내부에 resolve, reject를 매개변수로 갖는 콜백함수(executor)를 넣는다. 이렇게 만든 promise 변수에 then과 catch 메서드를 붙일 수 있다. 프로미스 내부에서 비동기 작업이 성공적으로 이행됐으면 resolve가 호출되고, then이 실행된다. 작업에서 오류가 발생한 경우 reject가 호출되고, catch가 실행된다. finally는 성공/실패 여부와 상관없이 실행된다.

 

const condition = true;  // true면 resolve, false면 reject

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

// 다른 코드가 들어갈 수 있음

promise
   .then(msg => {
      console.log(msg);  // 성공(resolve)한 경우 실행
   })
   .catch(err => {
      console.log(err);  // 실패(reject)한 경우 실행
   })
   .finally(() => {  
      console.log('무조건'); // 끝나고 무조건 실행
   });

 resolve에 넣어준 인수('성공')는 then의 매개변수로 전달되고, reject에 넣어준 인수('실패')는 catch의 매개변수로 전달된다. 즉, resolve('성공')이 호출되면 then의 msg는 '성공'이 된다.

 

 프로미스는 실행은 바로 하되 결괏값은 나중에 받는 객체이다. new Promise는 바로 실행되지만, 결괏값은 then을 붙였을 때 받게 된다.

 

✱ Promise 체이닝

 then, catch에서 다른 then, catch로 이어서 쓸 수 있다. 이전 then의 return값을 다음 then의 인자로 넘긴다. 프라미스 체이닝이 가능한 이유는 .then의 반환값이 프라미스이기 때문. 

new Promise((resolve, reject) => {
   setTimeout(() => resolve(1), 1000);
   
}).then(result => {

   alert(result);  // 1
   return result * 2;
   
}).then(result => {

   alert(result);  // 2
   return result * 2;
   
}).then(result => {

   alert(result);  // 4
   return result * 2;
   
});

1초 후 프라미스가 이행 .then 핸들러 호출 ➔ 반환값을 다음 .then에 전달, 다음 then 호출 : 이 과정 반복.

 

.then이 return으로 결괏값을 반환할 때 : then에서 반환한 프라미스가 자신의 결괏값으로 하여 이행.

   → Promise.resolve(결괏값) 즉, 다음 then에 결괏값을 인자로 전달.

 .then이 return하는 결괏값이 없을 때 : then에서 반환한 프라미스가 undefined를 결괏값으로 하여 이행.

   → Promise.resolve() 즉, 다음 then에 프라미스만 전달

오류 발생 시 : then에서 반환한 프라미스는 그 오류를 자신의 결괏값으로 하여 거부.

    → Promise.reject()

 

 .then이 프라미스를 return할 때 : 프라미스가 처리될 때까지 기다리다가 완료되면 그 결과를 받음

promise
   .then(msg => {
      return new Promise((resolve, reject) => {
         resolve(msg);
      });
   })
   .then(msg2 => {
      console.log(msg2);
      return new Promise((resolve, reject) => {
         resolve(msg2);
      });
   })
   .then(msg3 => {
      console.log(msg3);
   })
   .catch(err => {
      console.error(err);
   });

 처음 then에서 msg를 resolve하면 다음 then에서 msg2로 받을 수 있다. 여기서 다시 msg2를 resolve한 것을 다음 then에서 msg3로 받는다. 단, then에서 new Promise를 return해야 다음 then에서 받을 수 있다. 이 과정 중 reject되면 catch가 실행된다.

 

✱ Promise 여러 개를 한 번에 실행

Promise.all을 활용하면 간단히 가능!

const promise1 = Promise.resolve('성공1');
const promise2 = Promise.resolve('성공2');

Promise.all([promise1, promise2])
   .then(result => {
      console.log(result);
   })
   .catch(error => {
      console.error(error);
   });

 Promise.resolve는 즉시 resolve하는 프라미스를 만드는 방법이다. (Promise.reject도 있음) 프라미스가 여러 개 있을 때 Promise.all에 넣으면 모두 resolve가 될 때까지 기다렸다가 then으로 넘어간다. then의 result 매개변수에 각각의 프라미스 결괏값이 배열로 들어간다. Promise 중 하나라도 reject가 되면 catch로 넘어간다.

 

 

 

 

 

 


참고

 

책 - 조현영〔Node.js 교과서〕

코어 자바스크립트 블로그 - 프라미스 체이닝

MDN - Promise.prototype.then()

 

 

Comments