1.Synchronous Processing 동기
요청을 보내고, 응답이 올 때까지 대기한 후 응답이 오면 작업 진행
일의 순서가 중요한 경우 동기 처리를 진행하면 된다.
처리 순서가 보장되지만, 다음 응답이 오기까지 다른 작업을 수행할 수 없기에 비효율적일 수 있다.
console.log("첫 번째");
for (let i = 0; i < 1000000000; i++) {
// 무거운 작업
}
console.log("두 번째");
2. Asynchronous Processing 비동기
요청을 보내고, 응답을 기다리지 않고 다음 작업을 계속 해서 진행
일의 순서가 중요하지 않을 경우 효율적인 작업의 처리를 위하여 활용할 수 있다.
function sendTextMessage(message, callback) {
// 메시지를 보내는 비동기 작업을 가정해요.
setTimeout(() => {
console.log("문자 메시지 전송 완료: " + message);
callback(); // 응답이 도착하면 콜백 함수 호출
}, 2000); // 2초 후에 메시지 전송이 완료된다고 가정
}
console.log("메시지 보내기 시작");
sendTextMessage("안녕, 잘 지내?", function () {
console.log("메시지 전송 후 후속 작업 수행");
});
console.log("다른 작업 수행");
// 출력 결과:
// 메시지 보내기 시작
// 다른 작업 수행
// 문자 메시지 전송 완료: 안녕, 잘 지내?
// 메시지 전송 후 후속 작업 수행
import React, { useState, useEffect } from "react";
function App() {
const [post, setPost] = useState(null);
useEffect(() => {
console.log("시작");
.then((response) => response.json())
.then((json) => {
setPost(json);
console.log("데이터 가져오기 완료");
});
console.log("끝");
}, []);
return <div>{post ? <div>{post.title}</div> : <div>Loading...</div>}</div>;
}
export default App;
위와 같은 대표적인 예시가 비동기적 처리의 예시입니다.
3. Promise.. Promise.all.. Async/Await
자바스크립트는 기존에 비동기 작업을 처리할 때 콜백 함수를 많이 사용했었다.
그러나 콜백함수를 중첩해서 사용하다보면 가독성이 떨어지고, 코드가 복잡해진다. 아래의 코드에서도 확인이 가능하다.
이러한 상황을 콜백 지옥이라고 부른다 = 가독성이 떨어지고, 코드가 복잡한 상황 => 유지보수의 어려움, 인수인계의 어려움을 낳음.
import React, { useState, useEffect } from "react";
function App() {
const [post, setPost] = useState(null);
function doSomething(callback) {
setTimeout(() => {
console.log("작업 1 완료");
callback();
}, 1000);
}
function doSomethingElse(callback) {
setTimeout(() => {
console.log("작업 2 완료");
callback();
}, 1000);
}
function doThirdThing(callback) {
setTimeout(() => {
console.log("작업 3 완료");
callback();
}, 1000);
}
doSomething(() => {
doSomethingElse(() => {
doThirdThing(() => {
console.log("모든 작업 완료");
});
});
});
return <div>
{post ? <div>{post.title}</div> : <div>Loading...</div>}
</div>;
}
export default App;
Promise : 비동기 작업이 성공하거나 ,실패했을 때 성공과 실패에 대한 각각의 결과를 처리하는데에 필요.
3-1 Promise
Promise는 3가지 상태를 가진다.
대기 pending 이행되거나 ,거부되지 않을 상태,
이행 fullfilled 비동기 작업이 완료된 상태 resolve으로 인하여 pending에서 fullfilled
거부 Rejected// (1) 컴포넌트가 마운트될 때 fetch를 사용해 데이터를 비동기적으로 가져와요
react에서 데이터를 가져오는 작업은 비동기적으로 이루어지기에 promise가 많이 사용되어 진다.
// (1) 컴포넌트가 마운트될 때 fetch를 사용해 데이터를 비동기적으로 가져와요
// (2) Promise의 then 메서드를 사용해 데이터를 설정합니다.
// (3) 에러가 발생하면 catch 메서드를 통해 에러를 처리합니다.
import React, { useState, useEffect } from "react";
function App() {
const [post, setPost] = useState(null);
useEffect(() => {
.then((response) => response.json())
.then((json) => setPost(json))
.catch((error) => console.error("데이터 펫칭 오류! => ", error));
}, []);
return <div>{post ? <div>{post.title}</div> : <div>Loading...</div>}</div>;
}
export default App;
여러 비동기 작업을 처리할 때에는 promise.all 메서드가 사용되어 진다.
// 두 개의 API 호출을 병렬로 처리하는 예제
// 모든 비동기 작업이 완료되면 데이터를 설정합니다.
import React, { useState, useEffect } from "react";
function App() {
const [data, setData] = useState({ posts: [], users: [] });
useEffect(() => {
// 두 개의 처리를 동시에 시작해요.
Promise.all([
response.json()
),
response.json()
),
])
.then(([posts, users]) => {
setData({ posts, users });
})
.catch((error) => console.error("데이터 펫칭 오류! => ", error));
}, []);
return (
<div>
<h1>Posts and Users Data</h1>
<div>
<h2>Posts</h2>
{data.posts.length > 0 ? (
data.posts.map((post) => <div key={post.id}>{post.title}</div>)
) : (
<div>Loading posts...</div>
)}
</div>
<div>
<h2>Users</h2>
{data.users.length > 0 ? (
data.users.map((user) => <div key={user.id}>{user.name}</div>)
) : (
<div>Loading users...</div>
)}
</div>
</div>
);
}
export default App;
3-2 Async , await
Async, await 구문을 사용하면 비동기 코드를 동기 코드처럼 작성할 수 있어 가독성이 크게 향상이 된다.
try, catch 구문을 사용하여 비동기 작업에서 발생하는 오류를 간편하게 처리할 수 있다.
import React, { useState, useEffect } from "react";
function App() {
const [post, setPost] = useState(null);
useEffect(() => {
const fetchPost = async () => {
try {
const response = await fetch(
);
const data = await response.json();
setPost(data);
} catch (error) {
console.error("Error fetching post:", error);
}
};
fetchPost();
}, []);
return <div>{post ? <div>{post.title}</div> : <div>Loading...</div>}</div>;
}
export default App;