Front-End/자바스크립트

[자바스크립트] 비동기 콜백에서 Promise 사용 예제

shoney9254 2022. 6. 19. 21:02
반응형

Promise를 사용하는 이유 및 방법에 대해서 알아보기 위해 아래 예제를 따라 하면 된다. promise를 사용하지 않았을 때를 먼저 확인해보고 필요성을 알아가 보자.

 

1. Promise 사용하지 않는 방법

소스 코드

function isPositive(number, resolve, reject) {
   setTimeout(() => {
     if (typeof number === "number") {
         //성공 resolve
        resolve(number >= 0 ? "양수" : "음수");
     } else {
         //실패 reject
         reject("주어진 값이 숫자형 값이 아닙니다.");
      }
   }, 2000);
}

 

isPositive(
   "10",
   (res) => {
     console.log("성공적으로 수행됨 : ", res);
   },
   (err) => {
      console.log("실패 : ", err);
   }
);

결과

실패 : 주어진 값이 숫자형 값이 아닙니다.

isPositive 함수는 숫자인지 아닌지를 확인해주는 비동기 함수이다. 콜백 함수 2개를 받아서 출력해주는 형식이다. "10"이라는 문자를 입력했기 때문에, 결과는 실패라는 로그를 출력하게 된다. 

isPositive에 숫자를 10을 입력하게 되면 아래와 같은 결과가 나온다. 

결과

성공적으로 수행됨 : 양수

Promise 객체를 이용해서 위 코드를 작성해보도록 하자.

 

 

2. Promise 사용하는 방법

소스 코드

function isPositiveP(number) {
   const executor = (resolve, reject) => {
      setTimeout(() => {
        if (typeof number === "number") {
           //성공 resolve
           console.log(number);
          resolve(number >= 0 ? "양수" : "음수");
        } else {
           //실패 reject
          reject("주어진 값이 숫자형 값이 아닙니다.");
       }
      }, 2000);
   };

 

   const asyncTask = new Promise(executor);
   return asyncTask;
}

 

const res = isPositiveP(101);
console.log(res);
res
   .then((res) => {
     console.log("작업 성공 : ", res);
   })
   .catch((err) => {
     console.log("작업 실패 : ", err);
   });

결과

Promise는 Promise 객체를 반환하면서. then. catch로 작업 성공 여부를 알 수 있다. 

Promise는 콜백 함수로 성공(=resolve), 실패(=reject) 함수를 필요로 한다. 

성공한 값은 then 콜백함수로 사용되며, 실패한 것은 catch 콜백 함수가 사용된다.

 

 

3. Promise를 사용하지 않았을 때 콜백 지옥 예제

이전 게시글의 예제에서 들고 왔다. 동기, 비동기를 setTimeout 내장 함수로 이해하고 싶으면 아래 링크를 통해 이전 글을 보고 오도록 하자.

https://shoney.tistory.com/entry/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%8F%99%EA%B8%B0-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-%EB%B0%A9%EB%B2%95

 

[자바스크립트] 동기, 비동기 처리 방법

동기적으로 작업을 하면 하나의 task가 오랬동안 시간이 소요되면, 다른 작업들이 진행 못하고 대기하게 된다. 모든 작업들을 동시에 작업하기 위해서는 멀티 스레드로 작업하면 소요 시간을 줄

shoney.tistory.com

소스 코드

function taskA(a, b, cb) {
   setTimeout(() => {
      const res = a + b;
      cb(res);
   }, 3000);
}

 

function taskB(a, cb) {
   setTimeout(() => {
     const res = a * 2;
     cb(res);
   }, 1000);
}

 

function taskC(a, cb) {
   setTimeout(() => {
      const res = a * -1;
      cb(res);
   }, 1000);
}

 

taskA(3, 4, (resA) => {
   console.log("A TASK Result : ", resA);
   taskB(resA, (resB) => {
      console.log("B TASK Result : ", resB);
      taskC(resB, (resC) => {
         console.log("C TASK Result : ", resC);
      });
   });
});

결과

코드 끝
A TASK Result :7
B TASK Result :14
C TASK Result :-14

콜백 안에 콜백이 들어가 있고, 그것이 계속 반복되면 가독성도 떨어지게 된다.(계속 오른쪽으로 치우쳐지는 모양이 된다.) 이런 것을 콜백 지옥이라고 불린다. 이런 문제를 해결하기 위해서 promise를 사용한다. promise를 사용하면 어떻게 달라지는지 확인해 보자.

 

4. Promise를 통해 콜백 지옥을 벗어나는 방법

소스 코드

function taskA(a, b, cb) {
   return new Promise((resolve, reject) => {
     setTimeout(() => {
       const res = a + b;
       resolve(res);
     }, 3000);
   });
}

 

function taskB(a, cb) {
   return new Promise((resolve, reject) => {
      setTimeout(() => {
        const res = a * 2;
         resolve(res);
      }, 1000);
   });
}

 

function taskC(a, cb) {
   return new Promise((resolve, reject) => {
     setTimeout(() => {
         const res = a - 1;
        resolve(res);
      }, 1000);
   });
}

 

taskA(5, 1)
   .then((a_res) => {
     console.log("A Result : ", a_res);
     return taskB(a_res);
   })
  .then((b_res) => {
      console.log("B Result : ", b_res);
      return taskC(b_res);
   })
   .then((c_res) => {
      console.log("C Result : ", c_res);
   });

결과

A Result :6
B Result :12
C Result :11

return으로 다음 함수들을 불러 낼 수 있도록 되어있어서, 아래로 계속 나열되는 형태가 나온다. 깔끔하고 가독성이 높은 비동기 처리를 할 수 있다. 

 

반응형