[React][리액트를 다루는 기술] Promise, async/await, axios

uddi·2024년 9월 24일
0

React

목록 보기
18/19

📌 비동기 작업

웹 애플리케이션에서 서버의 API를 사용할 때 네트워크 송수신 과정에서 시간이 걸리기 때문에 작업이 즉시 처리되는 것이 아니라, 응답을 받을 때까지 기다렸다가 전달받은 응답 데이터를 처리한다

이 과정에서 해당 작업을 비동기적으로 처리하게 된다

동기적인 처리방식과 달리 비동기적으로 처리하게되면 웹 애플리케이션이 멈추지 않기 때문에 동시에 여러 가지 요청을 처리할 수도 있고, 기다리는 과정에서 다른 함수도 호출할 수 있다

서버 API를 호출할 때 외에도 비동기적으로 처리해야하는 경우는 setTimeout 함수를 사용해 특정 작업을 예약할 때

function printMe() {
  console.log('Hello World');
}
setTimeout(printMe, 3000);
console.log('대기 중...');

실행 결과

대기 중...
Hello World

setTimeout이 사용되는 시점에서 코드가 멈추지 않고 일단 위부터 아래까지 다 호출되고 3초 뒤에 printMe가 호출되는 것을 확인할 수 있다

JS에서 비동기 작업을 할 때 가장 흔히 사용하는 방법은 콜백 함수를 사용하는 것이다

위 코드에서는 printMe 함수 자체를 setTimeout의 인자로 전달해 주었다 👉 콜백 함수라고 한다

🍞 Promise

콜백 지옥 같은 코드가 형성되지 않게 하는 방안으로 ES6에 도입된 기능

  function increase(number) {
    const promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        const result = number + 10;
        if (result > 50) {
          const e = new Error("NumberTooBig");
          return reject(e);
        }
        resolve(result);
      }, 1000);
    });
    return promise;
  }

  increase(0)
    .then((number) => {
      // Promise에서 resolve된 값은 .then을 통해 받아 올 수 있음
      console.log(number);
      return increase(number);
    })
    .then((number) => {
      console.log(number);
      return increase(number);
    })
    .then((number) => {
      console.log(number);
      return increase(number);
    })
    .catch((e) => console.log(e)); // 도중에 에러가 발생한다면 .catch를 통해 알 수 있음

위와 같이 여러 작업을 처리해도 함수를 여러 번 감싸는 것이 아니라 .then을 사용하기 때문에 콜백 지옥이 형성되지 않는다

🍞 async/await

Promise를 더욱 쉽게 사용할 수 있도록 해 주는 ES2017(ES8) 문법

함수의 앞부분에 async 키워드를 추가하고 해당 함수 내부에서 Promise의 앞부분에 await 키워드를 사용한다

Promise가 끝날 때까지 기다리고, 결과 값을 특정 변수에 담을 수 있다

  function increase(number) {
    const promise = new Promise((resolve, reject) => {
      setTimeout(() => {
        const result = number + 10;
        if (result > 50) {
          const e = new Error("NumberTooBig");
          return reject(e);
        }
        resolve(result);
      }, 1000);
    });
    return promise;
  }

  async function runTasks() {
    // try-catch 구문을 사용하여 에러 처리
    try {
      let result = await increase(0);
      console.log(result);
      result = await increase(result);
      console.log(result);
      result = await increase(result);
      console.log(result);
    } catch (e) {
      console.log(e);
    }
  }

✏️ useEffect에서 async/await 사용

결론만 말하자면 useEffect에 등록하는 함수에 async를 붙이면 안 되고, useEffect 내부에서 async 키워드가 붙은 함수를 만들어 사용해야 한다

그렇게 해야하는 이뉴는 useEffect에서 반환해야 하는 값은 뒷정리 함수이기 때문이다

뒷정리 함수는 컴포넌트가 언마운트되거나 useEffect가 다시 실행될 때 이전에 실행된 작업을 정리하는 함수다
ex) 이벤트 리스너를 등록했다면 뒷정리 함수에서는 해당 리스너 제거

async 함수는 기본적으로 Promise를 반환하는데 useEffect는 Promise를 뒷정리 함수로 착각하기 때문에 리액트의 동작을 방해할 수 있다

📌 axios

axios는 현재 가장 많이 사용되고 있는 JS HTTP 클라이언트이며, HTTP 요청을 Promise 기반으로 처리한다는 특징이 있다

axios.get 함수는 파라미터로 전달된 주소에 GET 요청을 해 주고 .then을 통해 결과를 비동기적으로 확인할 수 있다

profile
거북이는 느리지만 결국 결승선을 통과한다

0개의 댓글