개발공부일지/React

React - JavaScript 응용하기 (Promise)

Hynn1429 2023. 8. 8. 11:46
반응형

안녕하세요.

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 은 실제 작은 페이지 구현을 하면서 보다 여러가지로 다루어보도록 하겠습니다.

 

감사합니다. 

반응형