[React.js] React 사용을 위한 자바스크립트 응용 - Promise

2022. 4. 30. 21:51·공부/React.js
반응형

 

React 게시글은 대부분 인프런의 '한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지' 강의를 기반으로 내용을 정리했습니다.

 

Promise

동기와 비동기에 대해 포스팅했을 때 마지막에 콜백 지옥(callback hell)을 잠깐 얘기했었다. Promise에 대해 알아보기 전에 먼저 비동기 작업이 가질 수 있는 3가지 상태에 대해 알아보자.

 

비동기 작업이 가질 수 있는 3가지 상태

Pending

  • 현재 비동기 작업이 진행중이거나, 현재 이 작업이 시작할 수 없는 문제가 발생했음을 의미한다.

Fulfilled

  • 이행 또는 성공 상태로 이 비동기 작업이 우리가 의도한대로 정상적으로 완료된 상태를 의미한다.

Rejected

  • 거부 또는 실패 상태로 비동기 작업이 모종의 이유(서버 비응답, 시간 지연 등)로 인해 실패했음을 의미한다.

resolve

  • 대기 상태에서 성공 상태로 변화하는 과정을 resolve(해결)이라 한다.

reject

  • 대기 상태에서 실패 상태로 변화하는 과정을 reject(거부)라고 한다.
반응형

resolve와 reject를 코드로 구현해보자.
2초 뒤에 비동기적으로 입력받은 값이 숫자인지 아닌지 판별하고, 만약 숫자면 양수와 음수인지 판별해주는 프로그램이다.

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

isPositive("12", (res)=>{
  console.log("성공적으로 수행됨 : " + res);
}, (err)=>{
  console.log("실패하였음 : ", err) // 출력
});

위의 코드는 비동기, 콜백 함수를 이용해서 만든 기본적인 프로그램이다. 이번에는 Promise를 사용해서 코드를 작성해보자.

 

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

isPositiveP(101);

Promise로 바꾸기 위해 새로운 함수를 만들었다. 아까 만든 코드와 다른 점은 executor 함수를 생성했다는 것이다. executor는 실행자. 즉 비동기 함수를 실질적으로 실행시키는 함수라고 일단 생각하면 된다. 

반응형
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);

Promise 사용을 위해 asyncTask Promise 타입 상수를 만들고, 그 상수를 return한다. isPositiveP()를 호출하면 이 return 값을 받기 위해 res라는 상수를 선언 후 호출하는 식으로 변경했다.
Promise 타입을 리턴하는 명령을 작성하면 함수의 설명에 Promise 객체를 반환한다고 업데이트된다.

 

이렇게 반환받은 Promise 객체를 사용하는 방법은 than과 catch를 사용하면 된다.

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

resolve를 수행한 결과 값을 then으로 가져올 수 있고, reject를 수행한 결과 값을 catch로 가져올 수 있다.

반응형

Promise를 이용해 콜백 지옥을 탈출하는 예제를 만들어보자. 저번 포스팅에 있었던 taskA, taskB, taskC 함수들!

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);
  }, 2000)
};

taskA(4, 5, (a_res) => { 
  console.log("A result : ", a_res); 
  taskB(a_res, (b_res) => { 
    console.log("B result : ", b_res); 
    taskC(b_res, (c_res) => { 
      console.log("C result : ", c_res); 
    }) 
  }) 
})

위 코드를 Promise로 변경해보자.

 

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

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

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

const res = taskA(5, 1);

res.then((a_res)=> {
  console.log("A result : ", a_res);
  taskB(a_res).then((b_res) => {
    console.log("B result : " , b_res);
    taskC(b_res).then((c_res) => {
      console.log("C result : ", c_res);
    });
  }); 
});

then을 이용해 콜백을 호출해봤는데....? 콜백 함수와 같은 then 지옥이 펼쳐졌다. 왜 이렇게 된거냐면 then을 일반 콜백함수 부르듯이 사용해서 그렇다. 호출 부분만 다시 변경해보자.

반응형
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 reult : ", c_res);
});

이번엔 return문이 새로 생겼다. 쉽게 말하자면 그냥 a_res의 값을 taskB함수에 매개변수로 주면서 호출함과 동시에 taskA의 콜백은 종료된다. 이렇게 then을 연쇄적으로 사용하는 것을 then chaining이라고 한다. 나는 음 솔직히 일반적인 콜백 함수나 then chaining이랑 뭐가 다른지 모르겠다. 생김새만 다른 거 같은데....라고 하는 순간 새로운 설명이 추가 됐다.

Promise를 이용하면 비동기 처리를 호출하는 코드와 결과를 처리하는 코드를 분리해줄수 있는 장점이 있다.

const bPromiseResult = taskA(5, 1)
.then((a_res) => {
  console.log("a result : ", a_res);
  return taskB(a_res);
});

bPromiseResult.then((b_res) => {
  console.log("b result : ", b_res);
  return taskC(b_res);
})
.then((c_res) => {
  console.log("c reult : ", c_res);
});

이런식으로.... 근데 아직 많이 안써봐서 그런지 뭐가 더 좋은건지 와닿지는 않는다.

 

반응형
저작자표시 비영리 변경금지 (새창열림)
'공부/React.js' 카테고리의 다른 글
  • [React.js] React 사용을 위한 자바스크립트 응용 - API & fetch
  • [React.js] React 사용을 위한 자바스크립트 응용 - async & await
  • [React.js] React 사용을 위한 자바스크립트 응용 - 동기&비동기
  • [React.js] React 사용을 위한 자바스크립트 응용 - Spread 연산자
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    SQL
    자바스크립트
    코딩테스트
    egov
    RESTful
    react
    알고리즘
    인프런
    토이프로젝트
    oracle
    프로그래머스
    springboot
    넥사크로
    개발자
    Spring
    운영체제
    프론트엔드
    토비의스프링부트
    JPA
    기출문제
    MSA
    IT
    SpringBoot를 이용한 RESTful Web Service 개발
    에러해결
    QueryDSL
    스프링부트
    Java
    백준
    전자정부프레임워크
    방통대
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
[React.js] React 사용을 위한 자바스크립트 응용 - Promise
상단으로

티스토리툴바