요청과 응답이 비순차적으로 일어나는 방식
요청을 보내고 응답을 기다리지 않고, 다음 작업을 계속 진행한다.
일의 순서가 중요하지 않은 경우, 효율적인 일처리가 가능하다.
Promise
는 Js에서 비동기 작업의 완료 또는 실패를 처리하기 위해 사용되는 객체
비동기 작업이 끝난 이후에 실행될 Callback()을 등록할 수 있는 메서드를 제공한다.
Promise는 세 가지 상태를 가진다.
resolve
나 reject
로 인해 다른 상태로 변경되기 전까지의 상태resolve
로 인해pending
-> Fulfilled
reject
로 인해 pending
-> rejected
Promise
객체는 then
, catch
, finally
메서드를 통해 이행되거나 거부된 이후의 동작을 정의할 수 있다.
const testPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if(success) {
resolve("성공");
} else {
reject("실패");
}
}, 2000);
});
testPromise
.then((result) => {
console.log(result); // Expected "성공"
})
.catch((error) => {
console.log(error); // Expected "실패"
})
JSONplaceholder API
사용해 데이터 가져오기import React, { useState, useEffect } from 'react';
function App() {
const [post, setPost] = useState(null);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => response.json())
.then((json) => setPost(json))
.catch((error) => console.error('fetch Error', error));
}, []);
return <div>{post ? <div>{post.title}</div> : <div>...loading</div>}</div>;
}
export default App;
무상태성(Statelses) : http는 상태를 유지하지 않는다. 요청은 독립적이며, 이전의 요청을 기억하지 않는다.
확장성 : http는 확장 헤더를 추가해 기능을 확장할 수 있다.
유연성 : http는 다양한 데이터 형식을 전송할 수 있다. (텍스트, 이미지, 비디오 등)
HTTP 메시지의 시작 줄과 HTTP 헤더를 묶어서 '요청 헤드(head)' 라고 부르며, 이와 반대로 HTTP 메시지의 페이로드는 '본문(body)'이라고 합니다.
Content-Type
, Content-Length
등 // GET
const fetchData = async () => {
try {
// get 요청 시, fetch는 method를 명시하지 않아도 돼요.
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts/1"
);
const result = await response.json();
setData(result);
} catch (error) {
console.error("Error fetching data:", error);
}
};
// POST
import React, { useState } from "react";
function App() {
const [title, setTitle] = useState("");
const [body, setBody] = useState("");
const [response, setResponse] = useState(null);
const handleSubmit = async (event) => {
event.preventDefault();
try {
const res = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST", // POST 요청
headers: { // Header
"Content-Type": "application/json",
},
body: JSON.stringify({ // Body
title: title,
body: body,
userId: 1,
}),
});
const result = await res.json();
setResponse(result);
} catch (error) {
console.error("Error creating data:", error);
}
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Title"
/>
<textarea
value={body}
onChange={(e) => setBody(e.target.value)}
placeholder="Body"
/>
<button type="submit">Create Post</button>
</form>
{response && <div>Created Post ID: {response.id}</div>}
</div>
);
}
export default App;
source code : Github
import { useEffect } from 'react';
import axios from 'axios';
function App() {
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get(
'https://jsonplaceholder.typicode.com/todos/1'
);
console.log(response);
} catch (error) {
console.error(error);
}
};
fetchData();
}, []);
return <></>;
}
export default App;
이제까지 맨날 response
찍고 response.data
를 새로운 변수에 담고 했었는데
아래처럼 구조분해 해서 가져올 수도 있었네..
// ... code
try {
const { data } = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
console.log(data);
} catch (error) {
console.error(error);
}
};
// src/axios/api.js
import axios from "axios";
const api = axios.create({
baseURL: 'http://localhost:3000',
});
api.interceptors.request.use(function (config) {
console.log("인터셉트 요청 성공");
return config;
});
api.interceptors.response.use(
function (response) {
console.log("응답 받음");
return response;
},
function (error) {
console.log("인터셉트 에러", error);
return Promise.reject(error);
}
);
export default api;