Promise
`JavaScript`에서 비동기 작업을 효과적으로 관리하고 처리하기 위한 중요한 도구 중 하나인 `Promise`에 대해 알아보겠습니다. 이 글에서는 `Promise`의 개념, 사용법, `resolve`와 `reject`의 역할, 그리고 `Promise`를 활용한 실제 예제에 대해 다룰 것입니다.
`Promise`는 비동기 작업의 성공 또는 실패를 나타내는 객체입니다. 주로 네트워크 요청, 파일 읽기, 데이터베이스 쿼리와 같은 비동기 작업을 다룰 때 사용됩니다. `Promise`는 세 가지 상태를 가질 수 있습니다.
- `Pending` (대기 중): 비동기 작업이 아직 완료되지 않은 상태입니다.
- `Fulfilled` (이행됨): 비동기 작업이 성공적으로 완료된 상태입니다.
- `Rejected` (거부됨): 비동기 작업이 실패한 상태입니다.
Promise 생성
`Promise`를 생성하려면 `new Promise`를 사용합니다. 아래는 기본적인 `Promise` 생성 예제입니다.
const myPromise = new Promise((resolve, reject) => {
// 비동기 작업 수행
if (비동기 작업 성공) {
resolve(결과 데이터);
} else {
reject(에러 메시지);
}
});
resolve와 reject 사용
`Promise` 내부에서 비동기 작업이 성공했을 때는 `resolve`를 호출하여 결과 데이터를 전달하고, 실패했을 때는 `reject`를 호출하여 에러 메시지를 전달합니다.
const myPromise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve("비동기 작업 성공");
} else {
reject("에러 발생");
}
}, 1000);
});
그리고 다양한 형태의 `Promise`를 만들 수 있습니다. 다음은 `try-catch`문을 활용한 `Promise`입니다.
function fetchUserData(userId) {
return new Promise(async (resolve, reject) => {
try {
const user = await getUserFromDatabase(userId);
if (!user) {
throw new Error("사용자를 찾을 수 없습니다.");
}
const userData = await getUserDataFromAPI(userId);
resolve(userData);
} catch (error) {
reject(error);
}
});
}
위의 코드에서는 `try` 블록 내에서 비동기 작업을 수행하고, 작업 중 에러가 발생하면 `catch` 블록으로 제어가 이동합니다. `catch` 블록에서는 에러를 처리하고 `reject`를 호출하여 `Promise`가 거부(rejected)됩니다. 이후 `catch` 메서드로 에러를 처리할 수 있습니다.
Promise 사용
`Promise`를 사용하여 비동기 작업의 결과를 처리할 때에는 `then`과 `catch` 메서드를 사용합니다.
myPromise
.then((result) => {
console.log("성공:", result);
})
.catch((error) => {
console.error("에러:", error);
});
`Promise`를 반환하는 함수를 호출하는 쪽에서 `try-catch` 블록을 사용하여 처리도 가능합니다.
async function main() {
try {
const userData = await fetchUserData(123);
console.log("사용자 데이터:", userData);
} catch (error) {
console.error("에러 발생:", error.message);
}
}
// main 함수 호출
main();
여러 개의 Promise 처리
여러 개의 `Promise`를 동시에 처리하거나 순차적으로 처리해야 할 때, `Promise.all`과 `Promise.race`를 활용할 수 있습니다.
- `Promise.all`: 여러 개의 Promise가 모두 이행될 때까지 기다렸다가 결과를 반환합니다.
- `Promise.race`: 가장 먼저 이행된 Promise의 결과 또는 거부된 Promise의 이유를 반환합니다.
// Promise.all 예제
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values); // [3, 42, "foo"]
});
// Promise.race 예제
const promiseOne = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'one');
});
const promiseTwo = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'two');
});
Promise.race([promiseOne, promiseTwo]).then((value) => {
console.log(value); // "two" - 빨리 끝난 Promise의 결과
});
실제 예제
`Promise`를 사용한 실제 예제를 통해 비동기 작업을 어떻게 처리하는지 살펴보겠습니다. (예: API 요청, 파일 읽기)
function fetchData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then((response) => response.json())
.then((data) => resolve(data))
.catch((error) => reject(error));
});
}
fetchData("<https://api.example.com/data>")
.then((data) => {
console.log("데이터 가져옴:", data);
})
.catch((error) => {
console.error("에러 발생:", error);
});
여기서 꼭 알아야 하는 것은 reject를 반환하게 되면 `try-catch`문에서는 바로 `catch`로 이동하기 때문에 예상치 못한 움직임을 볼 수 있습니다. 그러니 `Promise`에 대한 이해를 하고 사용하는 것을 추천합니다.
function fetchUserData(userId) {
return new Promise(async (resolve, reject) => {
try {
const user = await getUserFromDatabase(userId);
if (!user) {
throw new Error("사용자를 찾을 수 없습니다.");
}
const userData = await getUserDataFromAPI(userId);
resolve(userData);
} catch (error) {
reject(error);
}
});
}
async function main() {
try {
const userData = await fetchUserData(123);
console.log("사용자 데이터:", userData);
} catch (error) {
console.error("에러 발생:", error.message);
}
}
// main 함수 호출
main();
마무리
`Promise`는 `JavaScript`에서 비동기 작업을 처리하고 관리하는 강력한 도구입니다. 이 글에서는 `Promise`의 개념, 사용법, `resolve`와 `reject`의 역할, 그리고 실제 예제를 다뤄보았습니다. `Promise`를 활용하여 코드를 더욱 간결하고 효율적으로 작성할 수 있습니다. 추가로 `async/await`와 함께 사용하면 더 편리한 비동기 코드를 작성할 수 있습니다.
'Language > JavaScript' 카테고리의 다른 글
JavaScript Symbol - 심볼 (0) | 2023.10.24 |
---|---|
JavaScript) Closure 그는 무엇인가? (0) | 2023.09.13 |
LocalStorage, SessionStorage (0) | 2023.01.24 |
Script 태그 선언 위치에 따른 오류들 (0) | 2023.01.12 |
JavaScript(3) (0) | 2022.12.19 |