비동기, 그것은 axios, async 과 await

예진·2024년 10월 25일
0
post-thumbnail

axios를 사용하다보니까 모르는 것들이 나와서 ajax부터 비동기, Promise까지 찾아보게 되었다.
사실 내가 궁금했던 건 클론코딩중에 promise가 없는데 왜 promise 기반이라고 하지? 하는 코드가 있었다.

axios란?

  • Axios는 node.js와 브라우저를 위한 Promise 기반 HTTP 클라이언트이다.
    여기서 Promise가 나오는데, Promise가 그냥 비동기 객체? 중 하나다라고 생각했다.
    비동기함수를 처리하는 설명을 찾아 봤을 때 항상 봤던 것이 콜백함수였다.

콜백함수

  • 콜백 함수는 자바스크립트의 일급 객체 특성을 이용해 함수의 매개변수에 함수 자체를 넘겨, 함수 내에서 매개변수 함수를 실행하는 기법을 말한다.
  • 비동기함수에서 콜백함수를 사용하는 이유는 뭘까?
    비동기 처리는 앞서 처리되고 있는 연산이 끝나고 다음 연산이 진행되는 것이 아니라 동시에 연산이 처리하는 방식이다.
    그렇다면 비동기 함수는 위에 특성처럼 요청과 응답의 순서가 확실하지 않을 수 있다는 거다.
    하지만 그 요청과 응답의 순서가 필요할 때가 있는데, 그 때 콜백함수를 사용하는 거다.

getDB - 비동기 함수, main - 콜백함수
비동기처리의 결과가 필요했기 때문에 콜백함수로 비동기처리 값을 받아 결과를 표시한다.

function getDB(callback) {
    // 데이터베이스로부터 3초 후에 데이터 값을 받아온 후, 콜백 함수 호출
    setTimeout(() => {
        const value = 100;
        callback(value);
    }, 3000);
}

function main() {
    // 호출할 작업에 콜백 함수를 넘긴다
    getDB(function(value) {
        let data = value * 2;
        console.log('data의 값 : ', data);
    });
}
main();
  • 콜백함수가 없고 일반 함수로 data값을 콘솔에 띄워 보려고한다. 결과는 setTimeout에서 설정한 3초뒤에 비동기처리 값이 나오기때문에 콘솔에는 값이 나올 수가 없는 것이다.
    그 3초 뒤이던 3초 전이던 그 시간을 기다려 콘솔에 값을 띄우기 위해 콜백 함수를 사용한다.
  • 그렇기 때문에 콜백함수와 비동기 함수는 뗄 수 없는 사이다.
    하지만 비동기함수가 복잡하면 콜백함수 지옥에 빠져 읽기 힘들고 모양도 이쁘지 않은 함수가 생겨버린다.

Promise

갱장히 자세희 나와 있는 promise 문법

  • 뗄 수 없는 콜백함수, 비동기함수가 복잡해지면 콜백함수도 지저분해지는 한계를 promise 객체로 해소했다.
  • 자바스크립트 Promise 객체는 비동기 작업의 최종 완료(resolve) 또는 실패를(reject) 나타내는 Array나 Object 처럼 독자적인 객체라고 보면 된다.
  • 하지만 promise도 완벽한게 아니였으니, promise도 콜백함수처럼 복잡해질 수 있다는 것이다. 그래서 async/await 함수가 생겼다.

클론코딩 중 코드에서 아무리 promise가 없는데 어떤 걸 promise 라고하시는거지 그렇게 강의에서 말씀하신 이유를 찾았다.!

async/await는 프로미스를 기반으로 하지만, 마치 동기 코드처럼 작성할 수 있게 해준다.
출처: https://inpa.tistory.com/entry/🌐-js-async [Inpa Dev 👨‍💻:티스토리]

async/await 이란?

  • async/await은 promise를 대체 하기위해서 만들어진 것이 아니다.

    내부적으로는 여전히 Promise를 사용해서 비동기를 처리하고, 단지 코드 작성 부분을 프로그래머가 유지보수하게 편하게 보이는 문법만 다르게 해줄 뿐이라는 것이다. 

그르니까! 내가 궁금했던 'promise가 없는 어디있다는거여'의 결론
=> axios는 promise 기반을 하고 asysnc./await은 promise가 쓰일 때 문법적으로 깔끔하게 보이기 위해 사용해서 promise 객체나 용어가 보이지 않았던 것

import axios, {AxiosError} from 'axios';
try {//try에서 promise 부분은 무조건 실행
      setLoading(true);
      const response = await axios.post(`${Config.API_URL}/user`, {
        email,
        name,
        password,
      });
      console.log(response.data);
      Alert.alert('알림', '회원가입 되었습니다.');
      navigation.navigate('SignIn');
    } catch (error) { //에러 시 실행
      const errorResponse = (error as AxiosError).response;
      console.error(errorResponse);
      if (errorResponse) {
        Alert.alert('알림', errorResponse.data.message);
      }
    } finally {//실패했던 안했던 실행
      setLoading(false);
    }
  }, [loading, navigation, email, name, password]);
  

프로미스 객체, 객체 처리 얕게보기

  • 또궁금해지는 게있다. .then은 어떤 기능을 하지? 이다.
    async/await은 promise 객체가 사용하는 .then , .catch 메서드는 어떻게 사용되길래 async으로 보기 편하게 하나 싶었다.
    여기까지 도달하려면 프로미스 객체의 상태를 알 필요가 있다.

    • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
    • Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
    • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
  • 프로미스가 생성되면, 그 작업은 이미 진행 중이고 언젠가는 성공하거나 실패할 것이다. 그 성공/실패 결과를 .then / .catch / .finally 핸들러를 통해 받아 다음 후속 작업을 수행할 수 있다. 프로미스 핸들러는 프로미스의 상태에 따라 실행되는 콜백 함수라고 보면 된다.

  • promise()가 호출되는 부분의 function(tableData)에서 tableData가 뭐지 싶었는데,

만일 처리가 성공하여 프로미스 객체 내부에서 resolve(data) 를 호출하게 되면, 바로 .then() 으로 이어져 then 메서드의 콜백 함수에서 성공에 대한 추가 처리를 진행한다. 이때 호출한 resolve() 함수의 매개변수의 값이 then 메서드의 콜백 함수 인자로 들어가 then 메서드 내부에서 프로미스 객체 내부에서 다룬 값을 사용할 수 있게 된다.

function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get('url 주소/products/1', function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});

async/await 얕게 보기

async/await으로 promise 내타내기

  • async은 await를 사용하기 위한 선언문.
    async과 await은 항상 같이 붙어 다녀야하는 존재인 거다.
  • async 리턴값은 Promise 객체이다.
    async function에서 어떤 값을 리턴하든 무조건 프로미스 객체로 감싸져 반환된다.
async function func1() {
 const res = await fetch(url); // 요청을 기다림
 const data = await res.json(); // 응답을 JSON으로 파싱

  return 1;
}

const data = func1();
console.log(data); // 프로미스 객체가 반환된다
  • async의 함수 리턴값은 항상 promise이기 때문에 promise에서 사용하는 메서드 .then 도 사용할 수 있다. 하지만 프로미스헬 때문에 async을 사용하는 건데 남용해서는 안된다.
  • 그럼 .then을 써야되는 상황에서는 어떻게 해야할까?
    그 때 await을 사용한다.
    코드가 깊어지는 걸 방지하고 가독성을 높이게 한다!
// then 핸들러 방식
fetch(url)
    .then(res => res.json()) // 응답을 JSON으로 파싱
    .then(data => {
      // data 처리
      console.log(data);
    })
// await 방식
async function func() {
    const res = await fetch(url); // 요청을 기다림
    const data = await res.json(); // 응답을 JSON으로 파싱
    // data 처리
    console.log(data);
}
func();

그래서 우리는 콜백함수, promise, async/await 을 때에 따라 맞게 잘 활용해서 사용하면된다! 뭐가 더 낫고 뭐가 더 별로인 게 아닌 거시다~
사실 모든 키워드가 깊게보면 글의 양이 더 길어질텐데 내가 궁금했던 위주로 찾아봤다. 글들은 따로 읽어봐야겠다.






두리번 거린 글들
https://axios-http.com/kr/docs/intro
https://joshua1988.github.io/web-development/javascript/promise-for-beginners/
https://inpa.tistory.com/entry/%F0%9F%8C%90-js-async
https://inpa.tistory.com/entry/JS-%F0%9F%93%9A-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%B2%98%EB%A6%AC-Promise#%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8_%ED%94%84%EB%A1%9C%EB%AF%B8%EC%8A%A4_%EA%B0%9D%EC%B2%B4
https://ko.javascript.info/promise-basics

0개의 댓글

관련 채용 정보