[뉴스피드 개발일지 #1] 비동기와 API 호출

김유진·2022년 11월 9일
0

React

목록 보기
46/64

카테고리별로 최신 뉴스를 보여주는 뉴스 뷰어를 API를 활용하여 수행해보도록 하자!
먼저 API 호출을 잘 하기 위해서는 React의 비동기적인 작업에 대해서 이해하고 넘어갈 필요가 있다.

1. 비동기적인 React

웹 애플리케이션을 만들다 보면 시간이 걸리는 작업이 있습니다. 예를 들어 웹 애플리케이션 서버 쪽 데이터가 필요할 때는 Ajax 기법을 사용하여 서버의 API를 호출함으로써 데이터를 수신할 수 있다.

이렇게 서버의 API를 사용할 때는 네트워크 송수신 과정에서 시간이 걸리기 때문에 하나 들언왔다고 바로바로 작업이 즉시 처리되는 것이 아니라, 응답을 받을 때까지 기다렸다가 전달받은 응답 데이터를 모아모아 처리할 수 있다. 이 과정에서 작업이 비동기적으로 이루어지는 것이다.

비동기적으로 작업을 수행하게 된다면 요청이 끝날때까지 중지상태가 되거나 기다리는 불상사를 많이 줄일 수 있다는 점이다. 비동기적 처리는 웹 요청을 여러가지 동시에 처리할 수 있고 기다리는 과정에서 다른 함수도 호출하여 작업할 수 있기 때문이다.

우리가 이러한 작업을 임의로 조작할 수 있다.

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

이렇게 setTimeout함수를 사용하게 된다면 코드가 위부터 아래까지 모두 호출이 된 후에 3초 뒤에 우리가 지정해 준 printMe가 호출된다.

자바스크립트에서 비동기 작업을 할 때 가장 흔히 사용하는 방법은 콜백 함수를 이용하는 것인데, printMe가 3초 뒤에 호출되도록 이 함수 자체를 setTimeout의 인자로 전달해 주었는데, 이를 콜백 함수라고 한다.

콜백 지옥을 지양하자.

1초마다 숫자가 10씩 늘어나는 코드를 작성하고 싶어서 아래와 같이 코드를 작성했다.

function increase(number, callback) { 
  setTimeout(() => {
    const result = number +  10;
    if (callback) {
      callback(result);
    }
  }, 1000);
}

console.log('작업 시작');
increase(0, result => {
  console.log(result);
  increase(result, result => {
    console.log(result);
    	increase(result, result => {
          	console.log(result);
          	increase(result, result => {
              	console.log(result);
              	console.log('작업 완료);
                            });
            });
        });
  });

이렇게 콜백 안에 또 콜백을 넣어서 구현할 수 있는데 중첩이 너무 많아서 코드의 가독성이 나빠졌습니다! ㅜㅜ 이러한 형태의 코드를 콜백 지옥이라고 합니다.

Promise는 콜백 지옥 같은 코드가 나오지 않도록 하는 방안으로 ES6에 도입된 기능이다. 앞의 코드를 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;
}

increase(0)
	.then(number -> {
  	console.log(number);
	return increase(number);
})
.then(number => {
  console.log(number);
  reuturn increase(number);
})

...
.catch ( e => {
  //에러 발생시에 .catch 통하여 알 수 있음
  console.log(e);
});

이렇게 작업을 연달아 처리한다고 해서 콜백함수를 작성하지 않고 then을 이용하여 직관적으로 코드를 작성할 수도 있다.

async/await를 이용해볼까?

함수의 앞부분에 async 키워드를 추가하고 해당 함수 내부에서 Promise의 앞부분에 await 키워드를 사용하면 된다. 이렇게 하면 Promise가 끝날 때까지 기다리고 결과 값을 특정 변수에 담아 들고 다닐 수 있다.

function increase(nubmer) {
  const promise = new Promise((resolve, reject) => {
    //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 {
      let result = await increase(0);
      console.log(result);
      result = await increase(result);
      ...
    } catch(e) {
      	console.log(e);
    }
 }

2. Axios로 API 호출해서 데이터 받아오기

axios는 Promise를 기반으로 HTTP 요청을 처리합니당.
그래서 then문법을 이용하여 쉽게 요청을 처리할 수 있어요~

axios를 사용하기 전에 공식문서를 참고합시다.
https://axios-http.com/kr/docs/intro
당연히 axios는 설치해주어야죠?

yarn add axios

자, 이제 실제로 불러와보는 연습을 하면서 워밍업을 해보도록 합시다.

const onClick = () => {
    axios.get('https://jsonplaceholder.typicode.com/todos/1').then(response => {
      setData(response.data);
    });
  };

이렇게 get요청을 통하여 불러온 정보를 바탕으로 state를 변화시키고 있다.
위 코드에 비동기를 적용하여 더 예쁘게 코드를 작성해보자.

  const onClick = async () => {
    try {
      const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1', );
      setData(response.data);
    } catch (e) {
      console.log(e);
    }
  };

이렇게 작성해주면 비동기적으로 onClick을 구현 가능하다.

0개의 댓글