Web

Vue.js - API 호출 정리 - Promise

반응형
API  호출 호출 시점   - 페이지 로딩시 onMounted : DOM 이 준비된 뒤 실행
  - 값이 바뀔때 watch() : 반응형 데이터 변경시 
  - @click = "함수" : 사용자 UI 상호작용(인터렉션) 발생시
호출방법 fetch  Promise 기반
1. 기본적용

2. header 설정 필요, body 를 분명히 명시해야 하고, JSON.stringify() 수동파싱
3. 응답을 res.json() 직접호출
4. 구버전 브라우저 안됨
axios Promise 기반
1. npm install axios

2. header application/json 자동설정, 객체 전달시 자동 JSON처리- JSON.stringify() 
3. res.data 로 받음
   기타. timeout 지연, 인터셉터 지연, 폴리필지원으로 IE11 까지 지원(내부 XHR 사용) 
비동기 처리 흐름 정 1995~2014: 
콜백(callback)
- 초창기 JavaScript는 비동기 작업을 콜백 함수로 처리.
- 중첩 호출이 많아지면 "콜백 지옥(callback hell)" 발생.
2005: 
AJAX 등장
- XMLHTTPRequest(XHR)를 기반으로 서버와 비동기 통신 가능해짐.
- Gmail, Google Maps 등에서 사용되며 대중화.
2015 (ES6): 
Promise 도입
- 비동기 처리 후, 결과를 나중에 알려주는 객체
- 콜백 대신 `.then()` 체이닝으로 가독성과 에러 처리 개선.
promise     // then, catch 전에는 pending 상태
  .then(result => {
    console.log("Then:", result);  // fulfilled  성공하면 이 블록 실행
  })
  .catch(error => {
    console.error("Catch:", error);  // rejected 실패하면 이 블록 실행
  });

2015 (ES6): 
fetch API 등장
- XHR을 대체할 새로운 API로, Promise를 기반으로 동작.
- 네트워크 요청을 더 간단하게 작성할 수 있게 함.
1. fetch 는 Promise로 반환
const promise = fetch('/api/data');
console.log(promise); //  Promise { <pending> }

2. POST,PUT, PATCH 사용시 반드시 headers, body 직접작성
- Promise 형식 처리
fetch('/api/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json' // 꼭 명시!
  },
  body: JSON.stringify({
    name: '홍길동',
    age: 30
  })
})
  .then(res => res.json())// res.json()   도 Promise { <pending> }
  .then(data => console.log(data));
2017 (ES8): 
async/await 문법 도입

(작성 권장)
- Promise를 더 간결하고 동기 코드처럼 작성할 수 있게 함.
- 내부적으로는 Promise를 기반으로 동작하며, 가독성 향상.

- async 는 비동기작업(await)로 기다리다 결과를 res에 저장 
async/await 버전
async function postData() {
  try {
    const res = await fetch('/api/data', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name: '홍길동',
        age: 30
      })
    });

    const data = await res.json();  // 결과처리

  } catch (error) {
    console.error("에러 발생:", error);
    throw error; // 에러도 밖으로 던져줘야 catch에서 처리 가능
  }
}

 postData();
2016 : 
axios
import axios from 'axios';

async function postData() {
  try {
    const res = await axios.post('/api/data', {
      name: '홍길동',
      age: 30
    });
    res.data; // 결과처리
  } catch (error) {
    console.error("에러 발생:", error);
  }
}
postData();
2020 : 
Vue 3.x
<script setup>
import { ref, onMounted } from 'vue';
import axios from 'axios';

const result = ref(null);

onMounted(async () => {
  try {
    const res = await axios.get('/api/data');
    result.value = res.data;
  } catch (err) {
    console.error("에러:", err);
  }
});
</script>

 

Promise 비동기 처리 후, 결과를 나중에 알려주는 객체


Promise.resolve(value)  // 즉시 성공상태 promise 생성
Promise.reject(error)   // 즉시 실패상태 promize 생성
함수 Promise.all 모두성공시 실행 const fetchUser = () => axios.get('/api/user');
const fetchPost = () => axios.get('/api/post');
const fetchComment = () => axios.get('/api/comment');

Promise.all([fetchUser(), fetchPost(), fetchComment()])
  .then(([user, post, comment]) => {
    console.log("👤", user.data);
    console.log("📝", post.data);
    console.log("💬", comment.data);
  })
  .catch(err => {
    console.error("❌ 하나라도 실패함:", err);
  });
const urls = [ '/user', '/book', '/log' ];

const fetchAll = Promise.all(
  urls.map(url => fetch(url).then(res => res.json()))
);
Promise.race 빨리 끝나는 하나사용
실패가 먼저 끝나면 실패처리됨
const fetchFromA = () => axios.get('/api/a');
const fetchFromB = () => axios.get('/api/b');

Promise.race([fetchFromA(), fetchFromB()])
  .then(res => {
    console.log("🏁 먼저 도착한 응답:", res.data);
  })
  .catch(err => {
    console.error("❌ 에러:", err);
  });
const timeout = new Promise((_, reject) =>
  setTimeout(() => reject("⏰ 서버 너무 느림"), 3000)
);

// race로 둘 중 먼저 끝나는 걸 본다!
const result = await Promise.race([fetchAll, timeout]);
Promise.allSettled() 끝날 때까지 기다리고 성공(fulfilled)이든 실패(rejected)든 결과를 전부 알려줌 const p1 = Promise.resolve("✅ 성공1");
const p2 = Promise.reject("❌ 실패");
const p3 = Promise.resolve("✅ 성공2");

Promise.allSettled([p1, p2, p3])
  .then(results => {
    console.log(results);
  });

[
  { status: "fulfilled", value: "성공1" },
  { status: "rejected", reason: "실패" },
  { status: "fulfilled", value: "성공2" }
]

Promise.any() 성공한 것 중 가장 먼저 도착한 결과만 반환  
프로마이즈 체이닝  앞 단계 결과 등  Promize 실행 fetch('/api/step1')
  .then(res => res.json())
  .then(data1 => fetch(`/api/step2/${data1.id}`))
  .then(res => res.json())
  .then(data2 => console.log("최종 결과:", data2))
  .catch(err => console.error("에러:", err));