본문 바로가기
개발공부일지/React

React - JavaScript 응용하기 (Promise)

by Hynn1429 2023. 8. 8.
반응형

안녕하세요.

Hynn 입니다.

 

이번 포스팅에서는 Promise 객체에 대해서 알아보도록 하겠습니다.

Callback 지옥을 해결하기 위해서라고 했지만, JavaScript 에서 가장 많이 쓰이는 객체를 이해하면 보다 비동기를 효율적으로 처리할 수 있습니다.

 

시작해보도록 하겠습니다.

 

1. Promise 객체 알아보기

 

Promise 객체는 기본적으로 상태값을 가지고 있습니다.

이 상태는 3가지로 구분됩니다. 아래의 상태를 살펴보도록 하겠습니다. 

 

  • Pending - 대기 상태
  • Fulfilled - 성공 
  • Rejected - 실패 

Promise 객체는 기본적으로 비동기처리를 수행하면 Pending 이라는 대기중 상태를 갖습니다.

이 상태에서 작업을 수행하고 성공하면 Resolve 라고 하는 Fulfilled, 실패했을 경우 reject 라고 하는 Rejected 상태로 변하게 됩니다.

이를 이제 기초적으로 예제코드를 활용하여 살펴보도록 하겠습니다.

 

const verifyNumber = (number, resolve, reject) => {
  setTimeout(() => {
    if (typeof number === 'number') {
      resolve(number >= 0 ? 'Positive' : 'Negative');
    } else {
      // Reject
      reject('This is not a number');
    }
  }, 2000);
};

verifyNumber(
  5,
  (resolve) => {
    console.log(resolve);
  },
  (error) => {
    console.log(error);
  },
);

이 코드를 구성하는 것을 살펴보면, 먼저 verifyNumber 라는 함수를 선언하고, 매개변수로, number, 그리고 promise 객체의 상태에서 설명한대로, resolve, reject 를 추가합니다.

그리고 나서, 조건문을 사용해서 typeof 로 데이터타입이 숫자형인지를 확인하고, 만약 맞다면, 삼항연산자를 사용하여 resolve 내의 숫자가 양수인지, 음수인지를 판단하는 코드를 작성합니다.

 

만약 숫자가 아니라면 reject 를 실행하도록 작성합니다.

코드의 지연시간은 2초를 설정합니다. 

 

그리고 나서, 함수를 호출할때, resolve, reject 의 대한 영역을 코드로 구현합니다.

화살표 함수로 구현한 이 코드들은 각각 resolve, reject 에대한 처리를 담당합니다.

 

이렇게 실행하면 위의 예제코드는 5의 양수이므로, 결과가 "Positive" 가 출력되도록 구현됩니다.

이제 이를, Promise 객체로 변환해보도록 하겠습니다.

const isPositivePromise = (number) => {
  const execute = (resolve, reject) => {
    setTimeout(() => {
      if (typeof number === 'number') {
        console.log('Number is', number);
        resolve(number >= 0 ? 'Positive' : 'Negative');
      } else {
        console.log('Number is', number);
        reject('This is not a number');
      }
    }, 1000);
  };
  const asyncTask = new Promise(execute);
  return asyncTask;
};

 

기존의 코드와 유사하지만 다르게 구현된 코드를 살펴보겠습니다.

함수 내의 number 인자를 받고, 그 안에 execute 를 추가로 선언하여 resolve,reject 를 받은 뒤, 비동기 작업을 수행합니다.

그리고 asyncTask 라는 변수 내에 new Promise(execute) 로 결과값을 Promise 객체로 담습니다.

그리고 난뒤 , asyncTask 를 반환합니다. 

 

즉, asyncTask 가 Promise  객체를 생성하고, execute 를 담는 것이 됩니다.

이를 Console 로 출력해보면 "Promise { <pending> } " 이라는 형태로 출력될 것입니다.

 

이제 이를 활용하는 기초적인 방법은 아래와 같이 작성할 수 있습니다.

바로 "then" 메서드와, "catch" 메서드입니다.

 

기본적인 작성형태는 아래와 같이 이루어져 있습니다.

const res = isPositivePromise(10);
res
  .then((res) => {
    console.log('Result is', res);
  })
  .catch((err) => {
    console.log('Error is', err);
  });

response 를 의미하는 res 에 함수를 호출하고, 이를 점 표기법을 사용하여 then, catch 로 작성하는 방식입니다.

즉, then 에서는 정상적으로 수행되는 resolve, catch 는 reject 를 의미하는 error 를 처리하는 영역입니다.

이렇게 하면, 결과에 맞는 값이 출력됩니다. 

 

2.  async/await 사용하기

 

이러한 Promise 객체를 다루는 코드역시도 직관적으로 보여지지 않는 경우가 발생합니다.

이를 보다 직관적으로 사용하기 위해, async/await 를 사용하는 기본적 방법을 알아보도록 하겠습니다.

이는 Promise 객체를 보다 쉽게 다루게 해주는 기능이라고 이해하시면 되겠습니다. 

 

먼저 예시 함수를 하나 만들어 보겠습니다.

 

const delay = (ms) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, ms);
  });
};

const helloAsync = async () => {
  return delay(3000).then(() => {
    return 'Hello Async';
  });
};

 

비동기 함수를 작동하기 위해 위의 예제코드를 하나 만들었습니다.

위의 비동기 코드는, setTimeOut 을 매개변수로 받아, 동작하도록 구현했습니다.

이 경우 reject 는 고려하지 않고 resolve만 처리하도록 하였고, helloAsync 에서 delay 를 매개변수로 받아 then 메서드를 사용하여 동작하도록 처리했습니다.

 

하지만 async/await 의 기본적인 개념은 아래의 한줄로 정의할 수 있습니다

 

" 비동기코드를 동기코드처럼 동작하도록 도와주는 method"

 

async 와 await 은 항상 세트로 동작합니다.

async 의 주된 역활은 async 가 붙어있는 함수는 항상 결과값을 Promise 객체로 반환합니다.

즉, 결과가 Promise 객체가 아니더라도 JavaScript 에서는 이를 Promise 객체로 감싸서 값을 반환합니다.

 

await 은 항상 async 로 동작하는 함수 내에서만 사용할 수 있습니다.

단어의 뜻 그대로, Promise 객체의 Pending 상테에서 Fulfilled, rejected 의 결과를 기다리며, 결과가 나오면 값을 반환합니다. 당연히, rejected 가 발생하면, 이는 예외를 발생시키게 됩니다.

 

이를 사용하면 then, catch 보다 더 간결하게 비동기 함수를 동작할 수 있습니다.

 

이 async, await 은 실제 작은 페이지 구현을 하면서 보다 여러가지로 다루어보도록 하겠습니다.

 

감사합니다. 

반응형

댓글