프라이D
프라이Develog(❁´◡`❁)
프라이D
전체 방문자
오늘
어제
  • ALL (378)
    • TDD, Cleancode with JavaScr.. (5)
    • 프로젝트 (32)
      • work (3)
      • 직접 만드는 기술 블로그 (2)
      • 데일리 옥션 (19)
      • 모락모락 (8)
    • Computer Science (1)
    • Algorithm & 자료구조 (94)
      • 알고리즘 w.JavaScript (53)
      • 자료구조 (5)
      • (인프런) 자바스크립트 알고리즘 문제풀이 (34)
    • JavaScript (45)
      • JavaScript (41)
      • 모던 자바스크립트 Deep Dive (4)
    • WEB (13)
    • 회고 (12)
    • TIL (109)
    • WIL (7)
    • Stacks (20)
      • React.js (6)
      • Next.js (1)
      • Redux (3)
      • Node.js (2)
      • GIT (2)
      • SAP (1)
    • 15일 메이킹 프로젝트 (15)
    • 이전 기록 (14)
    • ETC. (5)
    • ---------------2021 (6)
      • 내일배움단-웹개발 5주 (2)
      • 정보처리기사 (4)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록

공지사항

인기 글

태그

  • MySQL
  • 내일배움단
  • 자바스크립트
  • 알고리즘
  • nomadcoder
  • JavaScript
  • 자바스크립트알고리즘
  • 자바스크립트비트마스크
  • Til
  • 코딩프로젝트
  • 투포인터알고리즘
  • 모던자바스크립트딥다이브
  • 코드스테이츠
  • nomadcoders
  • 국비지원
  • 비트마스크
  • vanilaJS
  • 스파르타코딩클럽
  • 2023 인프콘 후기
  • 내일배움카드

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
프라이D

프라이Develog(❁´◡`❁)

JavaScript/JavaScript

[JavaScript] Promise

2022. 7. 18. 21:23

본 게시글은 한입 크기로 잘라 먹는 리액트 (인프런) 강의를 보고 정리한 내용입니다.

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

  • Pending 대기상태 : 현재 비동기 작업이 진행 중 혹은 시작할 수 없는 문제가 있는 상황.
  • Fulfilled 성공
  • Rejected 실패

비동기 작업은 한 번 성공하거나 실패하면, 그것으로 끝이 난다.

  • Pending → Fulfilled : Resolve 해결
  • Pending → Rejected : Reject 거부

성공과 실패를 이렇게 두 가지 경우로 볼 수 있다.

비동기 처리 결과 핸들링 : 콜백 함수 버전

  • 콜백 함수를 활용하여 비동기 처리의 결과를 성공 resolve, 실패 reject 로 핸들링. (promise 객체 사용 x)
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 함수를 실행하며 순서대로, number, resolve 콜백함수, reject 콜백함수를 전달하고 있다.
  • isPositive 함수 내부에서는 setTimeout 비동기 함수가, number 매개변수의 type이 'number'일 경우를 성공으로
    그렇지 않은 경우 실패로 보고 전달된 resolve, reject 콜백함수에 결과값을 전달하여 실행한다. 
  • 각 콜백함수에서는 성공 결과를 res로, 실패 결과를 err 로 전달 받아 출력한다. 

비동기 처리 결과 핸들링 : promise 버전

  • 같은 작업에 promise 객체를 활용한 코드는 아래와 같음.
function isPositiveP(number) {
  // 비동기 작업을 실제로 수행할 executor 함수
  const executor = (resolve, reject) => {
    setTimeout(() => {
      if (typeof number === "number") {
        //성공 => resolve
        resolve(number >= 0 ? "양수" : "음수");
      } else {
        //실패 => reject
        reject("주어진 값이 숫자형 값이 아님.");
      }
    }, 2000);
  };

  // 프로미스 객체의 생성자로 방금 만든 비동기 힘수를 전달
  // 그 값을 상수 asyncTask에 저장하였음
  // 이렇게 저장하는 순간 executor 함수는 바로 실행된다.
  const asyncTask = new Promise(executor);

  // 프로미스를 반환한다 : 이 함수는 비동기 함수이다라는 의미.
  return asyncTask;
}

// promise 객체를 사용한 비동기 함수의 결과값을 저장하고,사용한다.
const res = isPositiveP(10);
res
  .then((res) => {
    console.log("작업 성공: ", res);
  })
  .catch((err) => {
    console.log("작업 실패: ", err);
  });
  • promise 객체를 리턴하는 함수의 결과값을 then 과 catch 메서드로 활용할 수 있다. 
  • res가 함수 isPositive 에 숫자 10을 넣어 호출한 결과 값이고, isPositive 함수는 내부 로직에 따라 resolve 혹은 reject를 처리한 뒤 이 결과값을 promise 객체인 asyncTask 에 담고 이를 리턴하고 있다. 
  • 즉 res 는 프로미스 객체이고, 처리 결과가 resolve 상태일 때 then 메서드를 사용해 비동기 처리 결과값을 받을 수 있다.
  • 만약 reject 상태라면 catch 메서드에서 실패한 결과값을 받을 수 있다. 

프로미스 체이닝 : 여러개의 프로미스 연결해서 사용하기

  • 3개의 비동기 처리 함수 taskA,B,C 가 있을 때 이를 promise를 사용해 작성하면 아래와 같음
function taskA(num1, num2) {
  // resolve, reject 콜백 함수를 인자로 받는 생성자 함수를
  // promise 객체에 바로 전달하고 이 결과값을 리턴하고 있다.
  // 이렇게 리턴한 promise 객체에서 then(), catch()로 그 결과값을 이용할 수 있다.
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const res = num1 + num2;
      resolve(res);
    }, 3000);
  });
}

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

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

then 체이닝 잘못된 사용 예시

  • 아래 코드처럼 사용하면 콜백을 전달하는 콜백 지옥과 다를 것이 없다. 계속 안으로 들여써지고 있는 것이 보일 것임...
taskA(5, 1).then((a_res) => {
  console.log(`taskA 결과값 ${a_res}`);
  taskB(a_res).then((b_res) => {
    console.log(`taskB 결과값 ${b_res}`);
    taskC(b_res).then((c_res) => {
      console.log(`taskC 결과값 ${c_res}`);
    });
  });
});

then 체이닝의 올바른 사용 예시

// taskA promise를 실행하고, taskB를 리턴 => 리턴 값도 프로미스 객체
// 이를 then 메서드로 계속 연결하여 사용할 수 있다.
// !then 체이닝! : 콜백 지옥 없이 비동기 처리의 다른 비동기 처리의 전달값으로 쓸 수 있다.
const bPromiseResult = taskA(5, 1).then((a_res) => {
  console.log(`taskA 결과값 ${a_res}`);
  return taskB(a_res);
});

bPromiseResult
  .then((b_res) => {
    console.log(`taskB 결과값 ${b_res}`);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log(`taskC 결과값 ${c_res}`);
  });

SUMMARY

  • promise 객체를 사용하면 콜백 지옥(비동기 처리 결과를 다른 비동기 함수의 전달 인자로 쓰기 위해 콜백을 계속 연결하다보면 엄청난 들여쓰기로 가독성이 굉장히 떨어진다.) 을 피하면서 비동기 작업을 할 수 있다. 
  • 비동기 작업이 성공한 상태를 reject, 실패한 상태를 resolve 로 볼 수 있고, 이 두 콜백 함수를 인자로 받는 함수를 생성자로 promise 객체를 생성한다. 
  • reject 상태의 결과값을 then 메서드로, resolve 즉 실패 상태의 결과값을 catch 로 받아 사용할 수 있다.
  • promise의 장점은 하나의 프로미스를 변수에 저장해두고 다른 작업을 한 뒤 다시 이어서 사용 할 수 있다는 것이다. (결과값에 then 메서드를 붙여 활용할 수 있다.) 

아직 비동기 함수와 프로미스의 실제 사용 상황을 경험한 적이 없어서 잘 와닫지가 않는다. 최대한 정리를 해보았는데 틀린 내용이 있을 수도 있다. 대신 오늘 이렇게 정리했으니 다음에 비동기와 프로미스에 대한 내용을 더 깊게 공부할 때는 조금 더 쉽게 이해할 수 있을 것 같다. 

 

참고자료

https://joshua1988.github.io/web-development/javascript/promise-for-beginners/

 

자바스크립트 Promise 쉽게 이해하기

(중급) 자바스크립트 입문자를 위한 Promise 설명. 쉽게 알아보는 자바스크립트 Promise 개념, 사용법, 예제 코드. 예제로 알아보는 then(), catch() 활용법

joshua1988.github.io

 

저작자표시 (새창열림)

'JavaScript > JavaScript' 카테고리의 다른 글

[JavaScript] 객체지향 프로그래밍 : OOP란 무엇인가?  (0) 2022.07.22
[JavaScript] 클로저와 커링 초간단 정리  (0) 2022.07.21
[JavaScript] 동기와 비동기  (0) 2022.07.16
[JavaScript]DocumentFragment 와 HTML5 template 태그 사용  (0) 2022.07.14
DOM : Document Object Model  (0) 2022.07.14
    'JavaScript/JavaScript' 카테고리의 다른 글
    • [JavaScript] 객체지향 프로그래밍 : OOP란 무엇인가?
    • [JavaScript] 클로저와 커링 초간단 정리
    • [JavaScript] 동기와 비동기
    • [JavaScript]DocumentFragment 와 HTML5 template 태그 사용
    프라이D
    프라이D
    틀린내용 정정 및 개선사항은 언제든지 댓글 달아주세요 :D

    티스토리툴바