FETCH, AXIOS (23/01/05)

nazzzo·2023년 1월 5일
0

1. AJAX & FETCH & AXIOS


Ajax는 클라이언트와 서버간 비동기적으로 데이터를 주고 받기 위한 기술입니다
오늘은 또 다른 방식의 비동기 통신 기술인 FetchAxios에 대해 알아보겠습니다


먼저 예제 코드를 통해 코드의 사용법부터 파악해보려 합니다


아래는 지금까지 써온 Ajax 방식의 예제 코드입니다

// 리퀘스트 메서드 생성
const request = ({ method, path, body }) => {
  return new Promise((resolve, reject) => {
    const host = `http://localhost:3000`;
    const xhr = new XMLHttpRequest();
    xhr.open(method, `${host}${path}`);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(body));

    xhr.onload = () => {
      if (xhr.readyState === 4 && xhr.status === 200) {
        resolve(JSON.parse(xhr.response));
      } else {
        reject(new Error("Error"));
      }
    };   
  }); 
};

// 코드 사용
const ajax = await request({method : "get", path :"/comments", body : null })
// console.log(ajax)

다음은 Fetch 방식의 예제 코드입니다

const response = await fetch("http://localhost:3000/comments", {
  method: "get",
  headers: {
    "Content-Type": "application/json"
  },
  body: null
})
// console.log(response)
const body = await response.json(); // 요청에 대한 응답 메세지를 객체화(JSON)해서 출력합니다

마지막으로 Axios 예제 코드입니다

  // axios (XMLHttpRequest를 바탕으로 만든 외장 모듈입니다)
  // <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  // 공식문서 : http://axios-http.com/kr/docs/example

  const getAxios = await axios.get('http://localhost:3000/comments')
  const postAxios = await axios.post('http://localhost:3000/comments', {
    // 두번째 인자값은 body 영역({})입니다
    content : 'axios test'
  })
  console.log(getAxios.data)
  console.log(postAxios.data)
})()



위 예제코드를 바탕으로 각각의 특징과 장단점을 정리하자면 다음과 같습니다

AJAX

장점
- 리퀘스트 메서드를 생성하고 나면 코드 사용이 간편합니다
단점
- 객체 생성 및 사전 작업이 매우 불편합니다
- Promis 기반이 아닙니다



FETCH

장점
- Promis 기반입니다
- 자바스크립트가 기본적으로 제공하는 내장 라이브러리입니다
단점
- 따로 JSON 변환작업이 필요합니다
- 코드 사용이 다소 번거롭고, 응답 바디 영역을 추출하려면 await두 번 필요합니다


AXIOS

장점
- Promis 기반입니다
- 사용법이 셋 중 가장 간편하고 많은 기능을 제공합니다
- 전송 데이터 타입의 기본값이 JSON 방식입니다
단점
- 별도의 라이브러리 설치 혹은 외부 링크 연결이 필요합니다


사실상 Fetch를 쓸 것이냐 Axios를 쓸 것이냐의 2택입니다만

자바스크립트가 자체적으로 더 나은 기능을 제공하지 않는 이상은
AXIOS를 사용하는 것이 가장 나아보이네요


2. AXIOS 사용 연습


지난 시간에 AJAX로 만든 댓글 기능구현 코드를 AXIOS로 고쳐보겠습니다



client javascript

const commentList = document.querySelector("#comment-list");
const addComment = document.querySelector(".submit");
const userid = "nazzzo";
const content = document.querySelector(".int");
const totalNumber = document.querySelector(".total-number");




// 현재 시간 (시간표현 수정용)
const getTimeNow = (date) => {
  let mm = date.getMonth() + 1;
  mm = (mm > 9 ? "" : "0") + mm;
  let dd = date.getDate();
  dd = (dd > 9 ? "" : "0") + dd;
  let yy = date.getFullYear();

  let hr = date.getHours();
  let mn = date.getMinutes();
  let sc = date.getSeconds();
  return [yy, mm, dd].join("-") + " " + [hr, mn, sc].join(":");
};
const thisTime = getTimeNow(new Date());
console.log(thisTime);


// 데이터 출력 함수
const displayResult = async () => {
  const getComments = await axios.get("http://localhost:3000/comments");
  const comments = getComments.data;
  totalNumber.innerHTML = `(${comments.length})`;

  // 댓글 리스트 초기화 필수
  commentList.innerHTML = "";

  for (const comment of comments) {
    const commentRow = document.createElement("li");
    commentRow.innerHTML = `
      <span class="comment-id">${comment.id}</span>
      <span class="comment-userid">${comment.userid}</span>
      <span class="comment-content">${comment.content}</span>
      <input class="comment-input" type="text" style="display :none" value="${comment.content}">
      <span class="comment-register">${comment.register}</span>
      <button class="comment-modify" style="display :none">수정</button>
      <button class="comment-delete">삭제</button>
    `;
    commentRow.setAttribute("data-id", comment.id);
    commentList.appendChild(commentRow);
  }

  // 댓글 삭제
  const dltComment = document.querySelectorAll(".comment-delete");
  dltComment.forEach((dltButton) => {
    dltButton.addEventListener("click", async () => {
      const li = dltButton.parentElement;
      const id = li.getAttribute("data-id");
      console.log(id);
      await axios.delete(`http://localhost:3000/comments`, {
        data: { id },
      });
      displayResult();
    });
  });

  // 댓글 수정
  const modiComment = document.querySelectorAll(".comment-content");
  modiComment.forEach((modiContent) => {
    modiContent.addEventListener("click", async () => {
      const li = modiContent.parentElement;
      const span = li.querySelector(".comment-content");
      const modiButton = li.querySelector(".comment-modify");
      const id = li.getAttribute("data-id");
      const input = li.querySelector(".comment-input");

      span.style.display = "none";
      input.style.display = "inline-block";
      modiButton.style.display = "inline-block";
      input.focus();
      modiButton.addEventListener("click", async () => {
        await axios.put(`http://localhost:3000/comments/${id}`, { id, content: input.value },
        );
        span.innerHTML = input.value;
        displayResult();
      });
    });
  });

  // 시간 표현 수정
  const regitTimeList = document.querySelectorAll(".comment-register");
  console.log(regitTimeList);

  regitTimeList.forEach((regitTimeRow, index) => {
    const parsedTimeRow = regitTimeRow.innerHTML.split(/[ :]/);
    const splitThisTime = thisTime.split(/[ :]/)
    console.log(parsedTimeRow);
    console.log(splitThisTime);
  
    if (
      splitThisTime[0] === parsedTimeRow[0] &&
      splitThisTime[1] === parsedTimeRow[1] &&
      splitThisTime[2] === parsedTimeRow[2]
    ) {
      regitTimeList[index].innerHTML = "방금전";
    } 
    else if (
      splitThisTime[0] === parsedTimeRow[0] &&
      splitThisTime[1] === parsedTimeRow[1] &&
      splitThisTime[2] !== parsedTimeRow[2]
    ) {
      regitTimeList[index].innerHTML = `${splitThisTime[2] - parsedTimeRow[2]}분전`;
    } else if (
      splitThisTime[0] === parsedTimeRow[0] &&
      splitThisTime[1] - parsedTimeRow[1] < 13
    ) {
      regitTimeList[index].innerHTML = `${splitThisTime[1] - parsedTimeRow[1]}시간전`;
    } else {
      regitTimeList[index].innerHTML = parsedTimeRow[0];
    }
  });
};
displayResult();

// 댓글 등록
(async () => {
  addComment.addEventListener("click", async () => {
    await axios.post("http://localhost:3000/comments", {
      userid,
      content: content.value,
    });
    displayResult();
  });
})();

여전히 코드가 멋이 없고 특히 수정 코드가 너무 더럽습니다 ㅠㅠ

이제 계속 미뤄두던 디자인 패턴에 대해서도 공부를 해야 할 것 같아요

0개의 댓글