비동기 작업을 보다 효율적으로 관리하는 데 필수적인 JavaScript의 Promise는 최신 버전에서도 다양한 개선을 통해 주니어 개발자들이 쉽게 비동기 작업을 다룰 수 있도록 발전하고 있습니다. 이번 글에서는 Promise의 핵심 기능을 최신 자료에 기반해 정리하고, 자주 쓰이는 메서드들을 설명해 보겠습니다.
Promise는 자바스크립트에서 비동기 작업의 상태를 관리하는 객체로, 비동기 작업이 완료되거나 실패했을 때 이를 처리하는 방법을 미리 정의할 수 있습니다. resolve 또는 reject가 호출될 때, 해당 Promise의 상태는 fulfilled 혹은 _rejected_로 변경됩니다. 이를 통해 코드를 더욱 간결하게 작성하고, 비동기 작업이 순차적으로 실행될 수 있도록 도와줍니다.
Promise.all()Promise.all()은 여러 비동기 작업을 병렬로 실행하고, 모든 작업이 성공했을 때 그 결과를 배열로 반환합니다. 단, 작업 중 하나라도 실패하면 전체가 실패로 처리됩니다.
const promise1 = Promise.resolve(5);
const promise2 = Promise.resolve(33);
const promise3 = new Promise((resolve) => setTimeout(resolve, 2000, '완료!'));
Promise.all([promise1, promise2, promise3])
.then((results) => console.log(results)); // [5, 33, "완료!"]
이 메서드는 다수의 작업을 동시에 실행할 때 유용하지만, 하나라도 실패하면 전체가 실패로 처리된다는 점을 유의해야 합니다.
Promise.allSettled()Promise.allSettled()는 Promise.all()과 비슷하지만, 모든 Promise가 완료될 때까지 기다리며 성공 여부에 관계없이 결과를 반환합니다. 이 경우 각 작업의 상태와 결과를 모두 알 수 있습니다.
const promise1 = Promise.resolve(9);
const promise2 = new Promise((_, reject) => setTimeout(reject, 4000, '에러 발생!'));
Promise.allSettled([promise1, promise2])
.then((results) => console.log(results));
// [{ status: "fulfilled", value: 9 }, { status: "rejected", reason: "에러 발생!" }]
실패한 작업도 함께 기록하기 때문에, 여러 작업의 결과를 한 번에 처리하는 상황에 적합합니다
Promise.any()Promise.any()는 여러 Promise 중 가장 먼저 성공한 하나만 반환하며, 나머지는 무시합니다. 이는 다수의 작업 중 하나만 성공하면 충분한 경우에 유용합니다. 단, 모든 작업이 실패하면 AggregateError라는 특별한 에러가 발생합니다.
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 2000, '2초 후 성공!'));
Promise.any([promise1, promise2])
.then((result) => console.log(result)) // "2초 후 성공!"
.catch((error) => console.log(error.errors)); // AggregateError
이 메서드는 특정 작업이 먼저 완료되는지 확인해야 할 때 유용하며, 최초 성공한 Promise의 값만 반환하는 것이 특징입니다
Promise.race()Promise.race()는 가장 먼저 완료된 Promise의 결과를 반환합니다. 결과가 성공이든 실패이든 가장 빠르게 완료된 작업이 반환됩니다.
const promise1 = new Promise((resolve) => setTimeout(resolve, 3000, '첫 번째 성공'));
const promise2 = new Promise((resolve) => setTimeout(resolve, 1000, '두 번째 성공'));
Promise.race([promise1, promise2])
.then((result) => console.log(result)); // "두 번째 성공"
이 메서드는 경쟁 상황에서 가장 빠르게 처리된 작업의 결과를 활용해야 할 때 유용합니다
비동기 작업을 효율적으로 관리하는 자바스크립트의 Promise는 개발자가 비동기 코드의 복잡성을 줄이고, 더욱 직관적인 코드 작성을 가능하게 합니다. Promise.all(), Promise.allSettled(), Promise.any(), Promise.race()와 같은 다양한 메서드를 활용하여 다양한 상황에서 비동기 작업을 최적화할 수 있습니다.
Promise.all()과 Promise.allSettled()를 적절히 활용해 보세요.Promise.any() 또는 Promise.race()를 사용해 보세요.아래는 복잡한 비동기 작업을 다루는 자바스크립트 Promise 예제입니다. 코드 내부에 각 메서드의 기능과 동작 원리에 대한 설명이 주석으로 기재되어 있습니다.
// 여러 비동기 작업을 복합적으로 처리하는 예제
// Promise 객체 3개를 생성합니다.
// 각 작업은 비동기적으로 실행되며, 일정 시간이 지난 후에 완료됩니다.
const task1 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Task 1 완료');
resolve('Task 1 결과');
}, 3000); // 3초 후에 완료
});
const task2 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Task 2 실패');
reject('Task 2 실패'); // 작업 2는 실패합니다.
}, 2000); // 2초 후에 실패
});
const task3 = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('Task 3 완료');
resolve('Task 3 결과');
}, 4000); // 4초 후에 완료
});
// 1. Promise.all() 사용 예제
// 모든 작업이 성공했을 때만 결과를 반환합니다.
// 하나라도 실패하면 전체가 실패로 처리됩니다.
Promise.all([task1, task2, task3])
.then(results => {
console.log('Promise.all 성공:', results);
})
.catch(error => {
console.log('Promise.all 실패:', error);
});
// task2가 실패하므로 Promise.all은 실패 처리됩니다.
// 2. Promise.allSettled() 사용 예제
// 각 작업의 성공 여부와 상관없이 모든 작업이 완료되면 결과를 반환합니다.
// 각각의 결과는 { status: 'fulfilled' or 'rejected', value or reason } 형태로 반환됩니다.
Promise.allSettled([task1, task2, task3])
.then(results => {
console.log('Promise.allSettled 결과:');
results.forEach((result, index) => {
console.log(`Task ${index + 1}:`, result);
});
});
// 모든 작업의 상태를 알 수 있으므로, 실패한 작업과 성공한 작업을 구분할 수 있습니다.
// 3. Promise.any() 사용 예제
// 가장 먼저 성공한 작업의 결과만 반환합니다.
// 만약 모든 작업이 실패하면 AggregateError가 발생합니다.
Promise.any([task1, task2, task3])
.then(result => {
console.log('Promise.any 성공:', result);
})
.catch(error => {
console.log('Promise.any 실패:', error.errors); // 실패한 이유들을 출력합니다.
});
// task1이 task2보다 늦게 완료되므로 task1의 결과를 반환합니다.
// 4. Promise.race() 사용 예제
// 가장 빨리 완료된 작업의 결과를 반환합니다. 성공이든 실패든 가장 먼저 완료된 작업의 결과가 반환됩니다.
Promise.race([task1, task2, task3])
.then(result => {
console.log('Promise.race 결과:', result);
})
.catch(error => {
console.log('Promise.race 실패:', error);
});
// task2가 가장 빨리 실패하므로 실패 결과가 출력됩니다.
task2가 실패하기 때문에 Promise.all은 실패로 처리됩니다.AggregateError를 발생시킵니다. 이 예제에서는 task1이 성공하여 그 결과가 반환됩니다.task2가 가장 빨리 실패하여 그 결과가 반환됩니다.
이 예제는 다양한 상황에서 Promise를 어떻게 활용할 수 있는지를 보여줍니다. 복잡한 비동기 작업에서 Promise를 효과적으로 관리하는 방법을 이해하는 데 도움이 됩니다.
아래는 POST 메서드를 사용하고 파라미터를 전달하는 고급 예제입니다. 여러 개의 API 요청을 동시에 처리하고, 각 요청에 대해 POST 방식으로 데이터를 전송하며, 다양한 상황에 맞게 Promise.all(), Promise.allSettled(), Promise.any(), Promise.race()를 활용하는 방법을 보여줍니다.
아래는 주어진 자바스크립트 코드를 HTML 페이지에서 사용할 수 있도록 한 예제입니다. HTML 페이지를 브라우저에서 실행하면 여러 API 요청을 비동기적으로 처리하며, POST 요청의 성공 및 실패 여부를 콘솔에 출력합니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Promise API Example</title>
</head>
<body>
<h1>Promise API Example with POST Requests</h1>
<button id="start">Start API Requests</button>
<script>
// POST로 데이터를 전송하는 API URL
const apiURL1 = 'https://jsonplaceholder.typicode.com/posts';
const apiURL2 = 'https://jsonplaceholder.typicode.com/posts';
const apiURL3 = 'https://jsonplaceholder.typicode.com/posts';
// POST 데이터를 준비하는 함수
const createPostData = (title, body, userId) => {
return JSON.stringify({
title: title,
body: body,
userId: userId
});
};
// POST 요청을 처리하는 함수 (fetch로 POST 요청)
const postData = (url, data) => {
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: data
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.catch(error => {
console.error(`Error posting to ${url}:`, error);
throw error;
});
};
// API 요청을 트리거하는 함수
document.getElementById('start').addEventListener('click', () => {
// 전송할 데이터를 정의
const data1 = createPostData('첫 번째 제목', '첫 번째 본문 내용', 1);
const data2 = createPostData('두 번째 제목', '두 번째 본문 내용', 2);
const data3 = createPostData('세 번째 제목', '세 번째 본문 내용', 3);
// 1. Promise.all(): 모든 요청이 성공해야만 다음 단계로 진행
Promise.all([postData(apiURL1, data1), postData(apiURL2, data2), postData(apiURL3, data3)])
.then((results) => {
console.log('Promise.all 성공:', results);
})
.catch((error) => {
console.error('Promise.all 실패:', error);
});
// 2. Promise.allSettled(): 각 요청의 성공 여부와 상관없이 모든 결과를 반환
Promise.allSettled([postData(apiURL1, data1), postData(apiURL2, data2), postData(apiURL3, data3)])
.then((results) => {
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`API ${index + 1} 성공:`, result.value);
} else {
console.error(`API ${index + 1} 실패:`, result.reason);
}
});
});
// 3. Promise.any(): 가장 먼저 성공한 요청만 처리
Promise.any([postData(apiURL1, data1), postData(apiURL2, data2), postData(apiURL3, data3)])
.then((result) => {
console.log('Promise.any 첫 번째 성공:', result);
})
.catch((error) => {
console.error('Promise.any 모든 요청 실패:', error.errors);
});
// 4. Promise.race(): 가장 빠르게 완료된 요청만 처리
Promise.race([postData(apiURL1, data1), postData(apiURL2, data2), postData(apiURL3, data3)])
.then((result) => {
console.log('Promise.race 첫 번째 완료:', result);
})
.catch((error) => {
console.error('Promise.race 첫 번째 실패:', error);
});
});
</script>
</body>
</html>
이 HTML 예제는 실제로 fetch를 이용하여 POST 방식으로 데이터를 전송하고, 각각의 Promise 메서드가 어떻게 동작하는지를 실시간으로 확인할 수 있도록 구성되었습니다.

이 코드는 웹 애플리케이션 개발에서 비동기 작업을 관리할 때 사용됩니다. 특히, 여러 개의 API 요청을 동시에 실행하거나, 각 요청의 결과를 개별적으로 처리해야 하는 복잡한 비동기 상황에서 매우 유용합니다. 이러한 기술은 다음과 같은 실제 상황에서 적용할 수 있습니다:
이처럼, 비동기 작업을 효율적으로 관리하는 것이 중요할 때 이러한 Promise 메서드를 적용하여 개발을 최적화할 수 있습니다.
| JavaScript : 부동소수점 연산 오차 문제와 해결 방법 (1) | 2025.03.07 |
|---|---|
| JavaScript : Hoisting(호이스팅) 최상단으로 끌어올려지는 현상 알아보자 (0) | 2025.03.05 |
| 사용자 이미지 업로드(JavaScript) -> Google Cloud Vision API 로 이미지 분석 (1) | 2024.11.20 |
| JS : 오늘, 내일 날씨 및 온도 구현하기 (openweathermap 활용) (1) | 2024.10.31 |
| Cross-site scripting (XSS) cheat sheet (0) | 2024.05.08 |