Programming/JavaScript

[JS] fetch 후 응답 데이터 처리 방법 (async, await. promise)

Pendine 2025. 1. 8. 18:37
728x90
const btn = document.querySelector(".btn");

const indexBtn = document.querySelector(".indexBtn");

const result = document.querySelector(".result");

// console.log(indexBtn.value);     // /api/index
// console.log(indexBtn.getValue);  // undefined
// console.log(indexBtn.getvalue);  // undefined
// console.log(indexBtn.getAttribute(value)); //corsTest.js:10 Uncaught ReferenceError: value is not defined

btn.addEventListener("click", (e)=>{
  e.preventDefault();
  console.log("클릭 확인");
  
  let test = fetch("http://127.0.0.1:8080/api/index");
  console.log( test );
  let jsondata = test.then( res => {
          res.json().then( answer => {
              console.log( answer.index);
            }) //크아아아아아!!! 무슨 중첩이냐 JS!!!!!
    // console.log( res.index );
    // console.log("res : " + res);
    //                       console.log("res.index : " + res.index );
                          return res;
                      })
                      .catch( (error) => {
                        // return new Error("응답오류")
                        console.log("error 발생 : " + error.message );
                       });
  // console.log("jsondata : " + jsondata);
  // console.log("jsondata : " + jsondata.index);
  // console.log();


});

indexBtn.addEventListener("click" , (e)=>{
  e.preventDefault();
  console.log("버튼의 value값으로 API 호출 테스트");
  let addUrl = indexBtn.value

  // 반환받은 res.json()이 Promise 객체기 때문에 .then() 필요
  let res = getData(`http://127.0.0.1:8080${indexBtn.value}`)
           .then( res => { 
            console.log( res );
            console.log("indexBtn.addEventListner getData then res : " + res ); 
            console.log(" : " + res.index ); 
            return res;
           })
           .catch( (error) => {
            // return new Error("응답오류")
            console.log("error 발생 : " + error.message );
           });

  console.log("res : " + res);
        
  
  // console.log(res.json());
 
})


async function getData( url = "" ){
  try{
    let response = await fetch( url );
    if(!response.ok){
      throw new Error("응답코드 오류 : " + response.status);
    }
    return await response.json(); // Promise 객체를 반환함
  } catch ( error ){
    console.error("fetch로 잡을수있는 error는 네트워크 오류뿐");
    throw error;
  }
}



//  // https://developer.mozilla.org/ko/docs/Web/API/Fetch_API/Using_Fetch
//  // POST 메서드 구현 예제
// async function postData(url = "", data = {}) {
//   // 옵션 기본 값은 *로 강조
//   const response = await fetch(url, {
//     method: "POST", // *GET, POST, PUT, DELETE 등
//     mode: "cors", // no-cors, *cors, same-origin
//     cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
//     credentials: "same-origin", // include, *same-origin, omit
//     headers: {
//       "Content-Type": "application/json",
//       // 'Content-Type': 'application/x-www-form-urlencoded',
//     },
//     redirect: "follow", // manual, *follow, error
//     referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
//     body: JSON.stringify(data), // body의 데이터 유형은 반드시 "Content-Type" 헤더와 일치해야 함
//   });
//   return response.json(); // JSON 응답을 네이티브 JavaScript 객체로 파싱
// }

// postData("https://example.com/answer", { answer: 42 }).then((data) => {
//   console.log(data); // JSON 데이터가 `data.json()` 호출에 의해 파싱됨
// });

 

내가 원한건 진짜 단순하게 요청 날려서 받아오는걸 바랬는데

XMLHttpRequest 도 배우고

promise 배우고

fetch배우고 했는데

역시 국비로 배우는 3개월로는 택도 없이 짧다

JS가 일급객체라 다루는걸 신경쓰지 않으면 상당히 까다로운데

반환하는 값의 형태도 알고있어야 원활하게 쓸수있음

 

 

  let test = fetch("http://127.0.0.1:8080/api/index");
  console.log( test ); // 프로미스 객체 반환
  let jsondata = test.then( res => {
                          res.json().then( answer => {
                 console.log( answer.index);

// fetch는 promise객체를 반환하고
// fetch로부터 반환받은 promise객체의 json() 메서드를 사용해야
// promise객체의 promise객체를 받환받을수있고
// promise객체의 promise객체에서 then을 사용해야 반환된 인자를 json문자열. js 객체로 활용할수음..
 

그러면 내가알기로는 

then에서 리턴된 값은 체이닝된 then으로 넘어가니까

  let jsondata = test.then( res => { return res.json() })
                     .then( res => console.log( res.index) )
                     .catch(error => console.error(error.message));
 
이렇게 구현하게되면 문제 해결됨
중첩이 될 필요가 없어지지.
 
실제로 해보니까 데이터도 제대로 표시됨.
 
======================================
 
처음에는 단순하게 html의 value속성에 집어넣은 값을 받아올수있을테니
버튼의 value속성에 api주소 넣고 버튼을 클릭하면 클릭된 버튼의 value를 가져오는것과
js 함수에다 박아버린것과 비교하려고 했던건데
 
html 의 value 가져와서 사용하는 버튼은 fetch할때 함수로 빼버리면서 
머릿속에서 빠그라지면서 시간 걸렸다.
 

그래서 전부 코드를 깔끔하게 정리하자면

 

const btn = document.querySelector(".btn");
const indexBtn = document.querySelector(".indexBtn");
const result = document.querySelector(".result");
 
const API_URL = 'http://127.0.0.1:8080';

// 깨달음 
//  비동기 함수를 사용하고 promise객체를 받지않으려면 전제조건이
//    1. 비동기 처리 함수를 사용한 곳에서 async / await를 사용하거나
//    2. async / await를 사용하지 않으면 then을 사용해야한다

btn.addEventListener("click", async (e)=>{
  e.preventDefault();
  
  let test = fetch( `${API_URL}/api/index`);
  console.log( test );
  let jsondata = await test.then( res => { return res.json() })
                     .then( res => {
                      console.log( " btn : res : " + res.index);
                      return res.index
                     } )
                     .catch(error => {return error.message} );

                     
  let addEl = document.createElement('p');
  addEl.textContent = "결과 : " + jsondata;

  result.appendChild(addEl);
});

indexBtn.addEventListener("click" , async (e)=>{  // 함수에 async 추가
  e.preventDefault();
  console.log("버튼의 value값으로 API 호출 테스트");

  let res = await getData( API_URL + e.target.value );  // await 추가
  
  console.log("indexBtn : " ,res);

  let addEl = document.createElement('p');
  addEl.textContent = "결과 : " + res;
  result.appendChild(addEl);
})


async function getData( url = "" ){
  try{
    let response = await fetch( url );

    if(!response.ok){
      throw new Error("응답코드 오류 : " + response.status);
    }

    let res = await response.json()
                      .then( res => {
                        console.log(res);
                        console.log(res.index);
                        return res.index;
                      });
                      
    console.log("res : " + res);
    console.log(res);
    return res;
  } catch ( error ){
    console.error("fetch로 잡을수있는 error는 네트워크 오류뿐");
    throw error;
  }
}

 

728x90