동기 vs 비동기
동기
- 서버에서 아직 처리를 안 해줬으면 동작이 멈추는 것
- 서버에 요청을 보낸 후 기다렸다가 해당 응답을 받아야 다음 동작을 실행
비동기
- 서버에서 아직 처리를 안 해줬지만 클라이언트에서 동작이 멈추지 않음
- 요청을 보낸 후 응답에 관계 없이 순차적으로 다음 코드를 먼저 실행
- AJAX, fetch, Promise, axios
1. AJAX
JavaScript를 사용하여 서버로부터 비동기적으로 데이터를 가져오는 기술
XML뿐만 아니라 JSON, 텍스트 등 다양한 데이터를 가져올 수 있음
옛날에 쓰던 기술
장점
- 오래된 브라우저에서 동작하기 때문에 호환성 높음
단점
- 코드가 길고 가독성이 떨어짐
- 비동기 처리 코드가 복잡해질 수 있음
const xhr = new XMLHttpRequest(); // XMLHttpRequest 객체 생성
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts', true); // GET 요청 설정
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) { // 요청이 완료되었을 때
if (xhr.status === 200) { // 응답이 성공적일 때
console.log(JSON.parse(xhr.responseText)); // JSON 데이터를 파싱해서 출력
} else {
console.error('Request failed');
}
}
};
xhr.send(); // 요청 전송
// 요청이 완료되고, 응답이 성공적일 때
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText)); // JSON 데이터를 파싱해서 출력
}
2. Fetch API
요즘 쓰는 기술
Promise 기반으로 데이터를 가져옴
-> fetch로 백엔드를 호출했을 때, fetch가 리턴해주는 형태 = Promise 객체
아직 데이터를 받아오지 않았어도 그냥 화면에 그려버림 -> 데이터가 없으니 제대로 그리질 못함
이걸 해결하기 위해서 async/await을 같이 사용한다.
장점
- 코드가 깔끔하고 이해하기 쉽다
- Promise를 기반으로 하므로 비동기 처리를 효과적으로 관리 가능
- 요즘 브라우저에서 기본적으로 지원
단점
- fetch는 네트워크 오류 외에 HTTP 오류(404, 500 등)를 자동으로 처리하지 않음
- 여러가지 기능이 없어서 하나하나 다 개발해야 함
GET 요청
fetch('https://jsonplaceholder.typicode.com/posts') // GET 요청
.then((response) => {
if (!response.ok) {
throw new Error('Network response was not ok'); // 오류 처리
}
return response.json(); // JSON 형식으로 변환
})
.then((data) => console.log(data)) // 성공적으로 데이터를 가져왔을 때
.catch((error) => console.error('Fetch error:', error)); // 오류가 발생했을 때
// GET은 주소 뒤의 객체가 생략되어 있다.
fetch('주소', { method: 'GET'}) // GET 방식이라는 것을 넣어줘야 한다.
POST 요청
// POSt 요청은 뒤의 객체가 생략이 안 된다.
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json', // JSON 형식임을 명시
},
body: JSON.stringify({
title: 'foo', body: 'bar', userId:
1
}),
})
.then((response) => response.json())
.then((data) => console.log('POST Response:', data))
.catch((error) => console.error('Error:', error));
3. Promise
비동기 작업을 처리하기 위한 객체
const getData = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true; // 성공 여부를 가정
if (success) {
resolve('Data loaded successfully');
} else {
reject('Error loading data');
}
}, 2000);
});
getData
.then((message) => console.log(message)) // 성공 시 실행
.catch((error) => console.error(error)); // 실패 시 실행
병렬처리
Promise.all을 사용하면 여러 개의 Promise를 병렬로 실행할 수 있음
// 병렬로 API 요청하기
const fetchUser = fetch('https://jsonplaceholder.typicode.com / users / 1');
const fetchPosts = fetch('https://jsonplaceholder.typicode.com / posts');
Promise.all([fetchUser, fetchPosts])
.then((responses) => Promise.all(responses.map((res) => res.json()))) // 응답 JSON 변환
.then(([user, posts]) => {
console.log('User:', user);
console.log('Posts:', posts);
})
.catch((error) => console.error('Error:', error));
4. Axios
Promise 기반의 HTTP 클라이언트
fetch보다 더 편리한 기능 제공
fetch는 json() 을 사용해서 JSON 형식으로 변환해줘야 하는데, axios는 자동으로 JSON 형식으로 바꿔줌
장점
- 여러가지 기능이 추가되어 있어 사용하기 편함
단점
- 라이브러리를 추가해서 사용해야 함
axios 설치
npm install axios
브라우저에서 사용할 경우 CDN 링크 추가
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
GET 요청
axios도 Promise 기반으로 동작하는 방식이기 때문에 보통 앞에 await을 붙여준다.
await axios.get('https://jsonplaceholder.typicode.com/posts')
.then((response) => {
console.log(response.data); // 응답 데이터
})
.catch((error) => {
console.error('Error fetching data:', error);
});
POST 요청
axios.post('https://jsonplaceholder.typicode.com/posts', {
title: 'foo',
body: 'bar',
userId: 1,
})
.then((response) => {
console.log('POST Response:', response.data);
})
.catch((error) => {
console.error('Error:', error);
});
async / awiat
자바스크립트에서 비동기 작업을 처리하는 최신 문법
Promise 기반으로 동작하며, 콜백이나 then 체인 대신, 동기 코드처럼 작성할 수 있도록 도와줌
보통 Promise를 사용하는 모든 곳에 async await을 달아서 사용
async : 함수를 비동기로 선언
await : Promise의 이행(성공) 또는 거절(실패)을 기다림
async function process() {
const step1 = await new Promise((resolve) =>
setTimeout(() => resolve('첫 번째 단계 완료'), 1000)
);
console.log(step1);
const step2 = await new Promise((resolve) =>
setTimeout(() => resolve('두 번째 단계 완료'), 1000)
);
console.log(step2);
}
process();
요청/응답 테스트
원하는 형태의 응답을 HTTP Response Body에 넣어주면 된다.
{
"products": [
{
"name": "상품01",
"price": 3000,
"image": "test1.png",
},
{
"name": "상품02",
"price": 5000,
"image": "test2.png",
},
{
"name": "상품03",
"price": 8000,
"image": "test3.png",
},
]
}
Generate 버튼을 클릭하면 Mock URL이 뜬다.
해당 URL을 요청 주소에 입력하면 된다.
const getProductList = async () => {
await axios
.get('https://run.mocky.io/v3/cbd6b559-a487-45e9-9497-695323ac8bbc') // mock 주소 입력
.then((response) => {
console.log(response.data); // 응답 데이터
})
.catch((error) => {
console.error('Error fetching data:', error);
});
}
getProductList();
콘솔창에 응답 데이터가 출력되는 걸 확인할 수 있다.
'FE > JavaScript' 카테고리의 다른 글
[JS] 배열 다루기 (0) | 2024.12.17 |
---|---|
[JS] DOM이란? / DOM 요소 다루기 (0) | 2024.12.17 |
[JS] 자바스크립트 기본 문법 (0) | 2024.12.16 |
[JS] 자바스크립트란? (0) | 2024.12.16 |