λΉλκΈ° μμ
(Promise)μμ λ°μνλ μλ¬λ₯Ό λͺ
μμ μΌλ‘ μ²λ¦¬νμ§ μμΌλ©΄, μ ν리μΌμ΄μ
μ΄ μ‘°μ©ν μ€ν¨νκ³ μ¬μ©μμκ² νΌλμ€λ¬μ΄ UIλ μλͺ»λ μνλ₯Ό 보μ¬μ€ μ μμ΅λλ€. μ΄λ λλ²κΉ
μ μ΄λ ΅κ² νκ³ μ¬μ©μ κ²½νμ ν¬κ² μ ν΄ν©λλ€. λͺ¨λ Promiseμλ .catch()λ₯Ό λΆμ΄κ±°λ async/await ꡬ문μμ try...catchλ₯Ό μ¬μ©νμ¬ μλ¬λ₯Ό μ‘κ³ , μ¬μ©μμκ² μ μ ν νΌλλ°±μ μ 곡ν΄μΌ ν©λλ€.
νλ‘ νΈμλ μ ν리μΌμ΄μ
μμ λ°±μλ API νΈμΆ, νμΌ μ½κΈ°, μ λλ©μ΄μ
μ§μ° λ± λΉλκΈ° μμ
μ νμμ μ
λλ€. μλ°μ€ν¬λ¦½νΈλ μ΄λ¬ν λΉλκΈ° μμ
μ κ²°κ³Όλ₯Ό Promise κ°μ²΄λ₯Ό ν΅ν΄ λ€λ£Ήλλ€. Promiseλ μ±κ³΅(resolve) λλ μ€ν¨(reject) μνλ₯Ό λνλ΄λλ°, κ°λ°μκ° reject μνλ₯Ό μ μ ν μ²λ¦¬(catch)νμ§ μμΌλ©΄ λ¬Έμ κ° λ°μν©λλ€.
Promiseκ° rejectλμμμλ λΆκ΅¬νκ³ .catch() λ©μλκ° μ°κ²°λμ΄ μμ§ μμΌλ©΄, ν΄λΉ μλ¬λ Unhandled Promise RejectionμΌλ‘ κ°μ£Όλ©λλ€. λλΆλΆμ λͺ¨λ λΈλΌμ°μ λ Node.js νκ²½μμλ μ΄λ¬ν μλ¬λ₯Ό μ½μμ κ²½κ³ λ‘ μΆλ ₯νμ§λ§, μ ν리μΌμ΄μ
μ μ€ν νλ¦μ λ©μΆμ§ μκ³ κ³μλ©λλ€. κ°λ°μ λꡬλ₯Ό μ΄μ΄λ³΄μ§ μμΌλ©΄ μ΄λ¬ν μ€λ₯κ° λ°μνλμ§ μκΈ° μ΄λ ΅μ΅λλ€.
λΉλκΈ° μμ
μ΄ μ€ν¨νλλ° μλ¬ μ²λ¦¬κ° μλ€λ©΄, μ ν리μΌμ΄μ
μ μν(state)λ μλν λλ‘ μ
λ°μ΄νΈλμ§ μμ΅λλ€. μλ₯Ό λ€μ΄, μ¬μ©μ μ 보λ₯Ό λΆλ¬μ€λ API νΈμΆμ΄ μ€ν¨νμ§λ§ μλ¬λ₯Ό μ‘μ§ μμΌλ©΄, isLoading μνκ° falseλ‘ λ°λλλΌλ user λ°μ΄ν°λ μ¬μ ν nullμ΄κ±°λ μ΄μ κ° κ·Έλλ‘ λ¨μμμ μ μμ΅λλ€. μ΄λ‘ μΈν΄ μ¬μ©μμκ² λΉ νλ©΄, μ€λλ λ°μ΄ν°, λλ κΉ¨μ§ UIκ° νμλ μ μμΌλ©°, μ΄λ μ¬κ°ν μ¬μ©μ κ²½ν μ νλ‘ μ΄μ΄μ§λλ€.
μλ¬κ° λ°μν΄λ λͺ νν λ©μμ§λ μ²λ¦¬ λ‘μ§μ΄ μμΌλ©΄, λ¬Έμ μ μμΈμ νμ νκΈ° λ§€μ° μ΄λ ΅μ΅λλ€. μ΄λ λΆλΆμμ, μ μλ¬κ° λ°μνλμ§ μΆμ νκΈ° μν΄ λ λ§μ μκ°κ³Ό λ Έλ ₯μ΄ νμνκ² λ©λλ€.
μΌλΆ λΉλκΈ° μμ μ μ±κ³΅ μ νΉμ μμμ ν΄μ νκ±°λ λ€μ λ¨κ³λ₯Ό μ§νν΄μΌ ν©λλ€. μλ¬ μ²λ¦¬ μμ΄ μ€ν¨νλ κ²½μ°, μ΄λ¬ν μμ ν΄μ λ‘μ§μ΄ μ€νλμ§ μμ μμ λμκ° λ°μνκ±°λ, μμμΉ λͺ»ν μν©μμ μ ν리μΌμ΄μ μ΄ μ€μλν μ μμ΅λλ€.
λΉλκΈ° μμ
μ μλ¬λ₯Ό ν¨κ³Όμ μΌλ‘ μ²λ¦¬νλ κ°μ₯ κΈ°λ³Έμ μΈ λ°©λ²μ Promise.prototype.catch() λ©μλλ₯Ό μ¬μ©νκ±°λ async/await ꡬ문 λ΄μμ try...catch λΈλ‘μ μ¬μ©νλ κ²μ
λλ€. μ΄λ€ λ°©λ²μ μ¬μ©νλ , μλ¬ λ°μ μ μ¬μ©μμκ² νΌλλ°±μ μ 곡νκ³ , μ ν리μΌμ΄μ
μ μνλ₯Ό μμ μ μΌλ‘ κ΄λ¦¬νλ κ²μ΄ μ€μν©λλ€.
Promise.prototype.catch() μ¬μ©νκΈ°λͺ¨λ Promise 체μΈμ λ§μ§λ§μ .catch() λ©μλλ₯Ό λΆμ¬ μλ¬λ₯Ό μ²λ¦¬ν©λλ€. μ΄λ Promise κΈ°λ° API (Fetch API λ±)λ₯Ό μ§μ μ¬μ©ν λ μ μ©ν©λλ€.
fetch('/api/data')
.then(response => response.json())
.then(data => {
// μ±κ³΅μ μΌλ‘ λ°μ΄ν° μ²λ¦¬
})
.catch(error => {
// μλ¬ λ°μ μ μ²λ¦¬
console.error('λ°μ΄ν°λ₯Ό κ°μ Έμ€λ μ€ μ€λ₯ λ°μ:', error);
// μ¬μ©μμκ² μ€λ₯ λ©μμ§ νμ λ±
});
async/awaitμ try...catch μ¬μ©νκΈ°κ°λ
μ± λμ λΉλκΈ° μ½λλ₯Ό μν΄ async/awaitλ₯Ό μ¬μ©νλ κ²½μ°, λκΈ° μ½λμ²λΌ try...catch λΈλ‘μ μ¬μ©νμ¬ μλ¬λ₯Ό μ²λ¦¬ν μ μμ΅λλ€. μ΄λ λ μ§κ΄μ μ΄κ³ 체κ³μ μΈ μλ¬ κ΄λ¦¬λ₯Ό κ°λ₯νκ² ν©λλ€.
async function fetchData() {
try {
const response = await fetch('/api/data');
if (!response.ok) {
// HTTP μλ¬ μν(4xx, 5xx)λ μλ¬λ‘ κ°μ£Όνμ¬ throw
throw new Error(`HTTP μλ¬! μν: ${response.status}`);
}
const data = await response.json();
// μ±κ³΅μ μΌλ‘ λ°μ΄ν° μ²λ¦¬
} catch (error) {
// μλ¬ λ°μ μ μ²λ¦¬
console.error('λ°μ΄ν°λ₯Ό κ°μ Έμ€λ μ€ μ€λ₯ λ°μ:', error);
// μ¬μ©μμκ² μ€λ₯ λ©μμ§ νμ λ±
}
}
μλ¬κ° λ°μνλ©΄ λ¨μν μ½μμ κΈ°λ‘νλ κ²μ λμ΄, μ¬μ©μμκ² μκ°μ μΈ νΌλλ°±μ μ 곡ν΄μΌ ν©λλ€. React μ»΄ν¬λνΈμμλ useState ν
μ μ¬μ©νμ¬ μλ¬ μνλ₯Ό κ΄λ¦¬νκ³ , μ΄ μνμ λ°λΌ UIλ₯Ό λ€λ₯΄κ² λ λλ§ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, μλ¬ λ©μμ§λ₯Ό νμνκ±°λ μ¬μλ λ²νΌμ μ 곡νλ λ±μ UX κ°μ μ κ³ λ €ν΄μΌ ν©λλ€.
// μμ: React μ»΄ν¬λνΈμμ μλ¬ μν κ΄λ¦¬
import React, { useState, useEffect } from 'react';
function MyComponent() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
setError(null); // μλ‘μ΄ μμ² μμ μ μλ¬ μ΄κΈ°ν
try {
const response = await fetch('/api/data');
if (!response.ok) {
throw new Error('λ°μ΄ν° λ‘λ μ€ν¨!');
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err);
console.error('λ°μ΄ν° λ‘λ© μ€ μλ¬:', err);
} finally {
setIsLoading(false);
}
};
fetchData();
}, []);
if (isLoading) return <div>λ‘λ© μ€...</div>;
if (error) return <div style={{ color: 'red' }}>μλ¬ λ°μ: {error.message}</div>;
return <div>λ°μ΄ν°: {JSON.stringify(data)}</div>;
}
μ ν리μΌμ΄μ
μ λ°μ κ±Έμ³ μ²λ¦¬λμ§ μμ Promise μλ¬λ₯Ό ν¬μ°©νκΈ° μν΄ window.addEventListener('unhandledrejection', ...)λ₯Ό μ¬μ©ν μλ μμ΅λλ€. μ΄λ μ΅μ’
λ°©μ΄μ μν μ νμ§λ§, κ°λ³ λΉλκΈ° μμ
μλ μ¬μ ν κ°λ³μ μΈ .catch()λ try...catch λΈλ‘μ μ μ©νλ κ²μ΄ μ’μ΅λλ€.
// React μ»΄ν¬λνΈ μμ
import React, { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
// μλ¬ μ²λ¦¬ μμ΄ μ¬μ©μ λ°μ΄ν°λ₯Ό κ°μ Έμ΄
fetch(`/api/users/${userId}`)
.then(response => response.json())
.then(data => {
setUser(data);
setIsLoading(false);
}); // π¨ .catch() λλ½!
// λ§μ½ fetchκ° μ€ν¨νλ©΄? λ€νΈμν¬ λ¬Έμ , μλ² μλ¬ λ±
// `user` μνλ null, `isLoading`μ falseκ° λμ΄
// UIλ λΉ νλ©΄μ΄κ±°λ λ‘λ© μ€νΌλκ° μ¬λΌμ§ μ±λ‘ μ΄μν μνλ₯Ό 보μ¬μ€.
// μ½μμλ Unhandled Promise Rejection κ²½κ³ λ§ λ¨μ.
}, [userId]);
if (isLoading) return <div>λ‘λ© μ€...</div>;
if (!user) return <div>μ¬μ©μ μ 보λ₯Ό λΆλ¬μ¬ μ μμ΅λλ€.</div>; // μ΄ λ©μμ§μ‘°μ°¨ μ λμ¬ μ μμ
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}// React μ»΄ν¬λνΈ μμ
import React, { useState, useEffect } from 'react';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null); // μλ¬ μν μΆκ°
useEffect(() => {
const fetchUser = async () => {
setIsLoading(true);
setError(null); // μλ‘μ΄ μμ² μ μλ¬ μ΄κΈ°ν
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
// HTTP μλ¬ μν (4xx, 5xx) μ²λ¦¬
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (err) {
console.error("λ°μ΄ν° λ‘λ© μ€ μλ¬ λ°μ:", err);
setError(err); // μλ¬ μν μ
λ°μ΄νΈ
} finally {
setIsLoading(false); // λ‘λ© μνλ νμ ν΄μ
}
};
fetchUser();
}, [userId]);
if (isLoading) return <div>λ‘λ© μ€...</div>;
if (error) return <div style={{ color: 'red' }}>λ°μ΄ν°λ₯Ό λΆλ¬μ€λ λ° μ€ν¨νμ΅λλ€: {error.message}</div>;
if (!user) return <div>μ¬μ©μ μ 보λ₯Ό μ°Ύμ μ μμ΅λλ€.</div>; // μλ¬κ° μλ κ²½μ°μ μ¬μ©μ μμ μ²λ¦¬
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}