자바스크립트를 공부하는 당신! Promise가 이해되지 않는다면,
비동기 작업을 좀 더 쉽게 생각해볼 수 있는 예시를 들어 설명해볼게요.
비동기 작업이란?
비동기 작업은 시간이 오래 걸리는 작업입니다. 예를 들어, 서버에서 데이터를 받아오는 작업이라든지, 파일을 읽는 작업이 해당됩니다. 이러한 작업들은 시간이 걸릴 수 있기 때문에, 완료까지 기다리지 않고 다른 일을 할 수 있도록 비동기적으로 처리됩니다.
Promise란?
Promise는 말 그대로 "약속"과 비슷합니다.
예를 들어, 누군가에게 "나는 5분 뒤에 너에게 돈을 줄게"라고 약속을 한다고 할 때, 그 사람은 약속을 지킬 수 있는 상태가 되기 전까지 기다려야 하죠. 그런데 이 약속을 Promise라고 생각할 수 있습니다.
Promise의 3가지 상태
대기 중 (pending):
이 상태는 "아직 작업이 끝나지 않았어"라는 상태입니다. 예를 들어, 친구에게 "5분 뒤에 돈을 줄게"라고 약속한 상태입니다.
이행됨 (fulfilled):
이 상태는 "약속을 지켰어"라는 상태입니다. 즉, 친구에게 돈을 줬고, 비동기 작업(예를 들어, 서버에서 데이터를 받는 작업)이 정상적으로 완료된 상태입니다.
거부됨 (rejected):
이 상태는 "약속을 지키지 못했어"라는 상태입니다. 예를 들어, 친구에게 "돈을 줄 수 없다"는 말처럼 비동기 작업이 실패했을 때 발생하는 상태입니다.
쉬운 예시 : 서버에서 데이터 요청 할 때
let promise = new Promise(function(resolve, reject) {
let success = true; // 서버 요청 성공 여부
if (success) {
resolve("데이터를 성공적으로 받았어요!"); // 작업이 성공적으로 끝난 경우
} else {
reject("서버 요청에 실패했어요."); // 작업이 실패한 경우
}
});
promise
.then(function(result) {
console.log(result); // 성공 시 실행되는 코드
})
.catch(function(error) {
console.log(error); // 실패 시 실행되는 코드
});
흐름:
- 대기 중(pending): 비동기 작업이 시작될 때
- 이행됨(fulfilled): 서버에서 데이터를 성공적으로 받아오면 resolve()가 호출
- 거부됨(rejected): 서버에서 데이터를 받아오지 못하면 reject()가 호출
Promise의 .then(), .catch() 메서드
- .then(): 작업이 성공적으로 끝났을 때 실행되는 함수입니다. 즉, 이행됨(fulfilled) 상태에서 호출됩니다.
이 메서드는 또 다른 Promise를 반환할 수 있습니다. - .catch(): 작업이 실패했을 때 실행되는 함수입니다. 즉, 거부됨(rejected) 상태에서 호출됩니다.
이 메서드는 주로 오류를 처리하는 데 사용됩니다.
then 과 catch 파악을 위한 또 다른 예시
const apiUrl = 'https://jsonplaceholder.typicode.com/users';
fetch(apiUrl)
.then(response => response.json())
.then(data => {
const users = data;
const usersDiv = document.getElementById('users');
users.forEach(user => {
const userElement = document.createElement('div');
userElement.innerHTML = `
<h2>${user.name}</h2>
<p>사용자 이름: ${user.username}</p>
<p>이메일: ${user.email}</p>
`;
usersDiv.appendChild(userElement);
});
})
.catch(error => {
console.error('데이터 가져오기 오류:', error);
});
Async와 Await
- 비동기 작업(asynchronous)을 동기처럼 읽기 쉽게 만드는 문법
- 기존에는 .then(), .catch()를 이어서 썼는데,
async 함수와 await 키워드를 사용하면 좀 더 순서대로, 직관적인 코드 작성이 가능
Async와 Await 이해를 위한 예시
async function fetchUsers() {
try {
const response = await fetch(apiUrl); // API에 요청 보내고 기다림
const users = await response.json(); // 응답을 JSON으로 바꿔서 users에 저장
const usersDiv = document.getElementById("users"); // HTML 요소 찾기
users.forEach((user) => {
// 사용자 정보를 반복하며 화면에 표시
const userElement = document.createElement("div");
userElement.innerHTML = `
<h2>${user.name}</h2>
<p>사용자 이름: ${user.username}</p>
<p>이메일: ${user.email}</p>
`;
usersDiv.appendChild(userElement);
});
} catch (error) {
// 에러가 발생하면 콘솔에 표시
console.error("데이터 가져오기 오류:", error);
}
}
fetchUsers(); // 함수 실행
요약
대기 중 (pending): 아직 비동기 작업이 완료되지 않은 상태
이행됨 (fulfilled): 비동기 작업이 성공적으로 끝난 상태
거부됨 (rejected): 비동기 작업이 실패한 상태
Promise를 사용하면 비동기 작업을 처리할 수 있고, 그 안에서 적절한 메서드를 사용하면 됩니다.