
📅 2025-11-06
➡️ 웹 비동기 프로그래밍에 대해 새롭게 알게 된 것 또는 헷갈리는 부분 정리
// 비동기 작업 수행
const myPromise = new Promise((resolve, reject) => {
if (/* 작업이 성공하면*/) {
resolve("성공 메시지");
} else {
reject("실패 메시지");
}
});const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
// 성공 여부를 나타내는 플래그
const success = true;
if (success) {
// resolve()가 호출되면 Promise는 '성공(fulfilled)' 상태가 됨
// 인자로 전달한 값은 .then()의 콜백 함수로 넘어감
resolve("작업이 성공적으로 완료되었습니다!");
} else {
// reject()가 호출되면 Promise는 '실패(rejected)' 상태가 됨
// 인자로 전달한 값은 .catch()의 콜백 함수로 넘어감
reject("작업이 실패했습니다.");
}
}, 2000); // 2초 후에 결과 반환
});
myPromise
.then((result) => {
console.log(result); // 성공 시 메시지 출력
})
.catch((error) => {
console.log(error); // 실패 시 에러 메시지 출력
});import React, { useState, useEffect } from "react";
function App() {
const [message, setMessage] = useState("타이머 시작");
// useEffect 훅을 사용하여 컴포넌트가 마운트되었을 때 실행될 효과를 정의
// 빈 배열 []을 두 번째 인자로 넘겨주어, 이 효과가 컴포넌트가 처음 렌더링 된 후 한 번만 실행
useEffect(() => {
// delay 함수 정의
// (1) delay 함수는 Promise 객체를 새로(new) 만들어 반환
// 여기서 Promise는 객체를 생성하기 위한 생성자
// (2) 만들어진 promise 객체는 주어진 밀리초(ms)만큼 동작을 지연시킴
// (1) delay함수는 주어진 밀리초(ms)만큼 지연시키는 Promise를 반환
// (2) setTimeout을 사용하여 지정된 시간(ms) 후에 resolve를 호출
// (3) 따라서, 지정된 시간(ms) 후에 pending -> fulfilled로 상태가 바뀜
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// (1) delay 함수를 호출하여 2000밀리초(2초) 동안 지연시킴
// (2) delay 함수가 반환하는 Promise가 완료되면 then 메서드가 호출되고, 이 메서드 안의 콜백 함수가 실행됨
// (3) 이 콜백 함수는 setMessage를 호출하여 message 상태를 "2초 후 메시지 변경"으로 업데이트
delay(2000).then(() => setMessage("2초 후 메시지 변경"));
}, []);
// 초기 상태는 "타이머 시작"이며, 2초 후에는 "2초 후 메시지 변경"으로 업데이트
return (
<div>
<h1>{message}</h1>
</div>
);
}
export default App;데이터 가져올 때
import React, { useState, useEffect } from "react";
function App() {
const [post, setPost] = useState(null);
useEffect(() => {
// 1. 컴포넌트가 마운트될 때 fetch를 사용해서 데이터를 비동기적으로 가져옴
fetch("https://jsonplaceholder.typicode.com/posts/1")
// 2. Promise의 then 메서드를 사용해서 데이터 설정
.then((response) => response.json())
.then((json) => setPost(json))
// 3. 에러가 발생하면 catch 메서드를 통해 에러 처리
.catch((err) => console.error("데이터 요청 실패:", err));
}, []);
return <div>{post ? <div>{post.title}</div> : <div>Loading...</div>}</div>;
}
export default App;
fetch()함수는 Promise를 반환함.then()은 성공 시 실행, .catch()는 실패 시 실행.finally()로 성공/실패 상관없이 마지막 정리 작업도 가능Promise.all()
import React, { useEffect, useState } from "react";
export default function App() {
const [data, setData] = useState({ posts: [], users: [] });
useEffect(() => {
Promise.all([
fetch("https://jsonplaceholder.typicode.com/posts").then((r) => r.json()),
fetch("https://jsonplaceholder.typicode.com/users").then((r) => r.json()),
])
.then(([posts, users]) => setData({ posts, users }))
.catch((e) => console.error("데이터 로드 실패:", e));
}, []);
return (
<div>
<h1>Posts & Users</h1>
<section>
<h2>Posts</h2>
{data.posts.length ? (
data.posts.map((p) => <div key={p.id}>{p.title}</div>)
) : (
<p>Loading...</p>
)}
</section>
<section>
<h2>Users</h2>
{data.users.length ? (
data.users.map((u) => <div key={u.id}>{u.name}</div>)
) : (
<p>Loading...</p>
)}
</section>
</div>
);
}
Promise.all() 은 여러 개의 비동기 요청을 한 번에 실행하고, 모든 요청이 끝나면 결과를 한 번에 받아볼 수 있음async 함수는 항상 Promise를 반환await 키워드는 Promise가 완료될 때까지 기다린 뒤 결과를 반환import React, { useState, useEffect } from "react";
export default function App() {
const [post, setPost] = useState(null);
useEffect(() => {
const load = async () => {
try {
const res = await fetch("https://jsonplaceholder.typicode.com/posts/1");
const data = await res.json();
setPost(data);
} catch (err) {
console.error("에러 발생:", err);
}
};
load();
}, []);
return post ? <h3>{post.title}</h3> : <p>Loading...</p>;
}async/await은 try-catch로 에러를 한 곳에서 처리할 수 있고, .then().catch()보다 코드 흐름이 자연스럽게 이어짐| 메서드 | 역할 | 설명 |
|---|---|---|
| GET | 조회(Read) | 서버로부터 데이터를 요청. 요청 데이터가 URL에 포함됨 |
| POST | 생성(Create) | 서버에 데이터를 제출하여 새로운 리소스를 생성. 데이터는 요청 본문에 포함됨 |
| PUT / PATCH | 수정(Update) | 서버의 기존 리소스를 수정. 요청 본문에 수정할 데이터 포함 |
| DELETE | 삭제(Delete) | 서버의 특정 리소스를 삭제 |
REST API
특정 자원(Resource)을 URL로 표현하고, HTTP 메서드를 조합하여 자원의 행위를 나타내는 방식
즉, 메서드 + URL 조합으로 API의 의미를 표현한다고 보면 됨