일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 프론트엔드
- 논리연산자
- if else
- 변수
- typeof
- 속성
- for in
- Methods
- justify-content
- 함수
- flex-wrap
- ELSE
- properties
- 문자열
- javascript
- boolean
- 함수표현식
- 함수선언식
- frontend
- 반복문
- 화살표함수
- align-content
- 타입
- flex-direction
- for of
- 비교연산자
- flex
- 기초
- for
- 조건문
- Today
- Total
하얀 코딩
[JavaScript - 23] Promise API 본문
Promise.prototype.all()
let promise = Promise.all([...promises...]);
Promise.all()은 여러 개의 비동기 작업을 동시에 처리하고 싶을때 사용합니다. 인자로는 배열을 받습니다.
해당 배열에 있는 모든 Promise에서 executor 내 작성했던 코드들이 정상적으로 처리가 되었다면
결과를 배열에 저장해 새로운 Promise를 반환 해줍니다.
앞서 배운 Promise chaining을 사용했을 경우는 코드들이 순차적으로 동작되기 때문에 총 6초의 시간이 걸리게 됩니다.
또한, 같은 코드가 중복되는 현상도 발생하게 됩니다.
// Promise chaining을 사용
const promiseOne = () => new Promise((resolve, reject) => setTimeout(() => resolve('1초'), 1000));
const promiseTwo = () => new Promise((resolve, reject) => setTimeout(() => resolve('2초'), 2000));
const promiseThree = () => new Promise((resolve, reject) => setTimeout(() => resolve('3초'), 3000));
const result = [];
promiseOne()
.then(value => {
result.push(value);
return promiseTwo();
})
.then(value => {
result.push(value);
return promiseThree();
})
.then(value => {
result.push(value);
console.log(result);
// ['1초', '2초', '3초']
})
이러한 문제들을 Promise.all()을 통해 해결할 수 있습니다. Promise.all()은 비동기 작업들을 동시에 처리합니다.
따라서 3초 안에 모든 작업이 종료됩니다. 또한 Promise chaining로 작성한 코드보다 간결해진 것을 확인할 수 있습니다.
// Promise.all 사용
Promise.all([promiseOne(), promiseTwo(), promiseThree()])
.then((value) => console.log(value))
.catch((err) => console.log(err));
2초 후 두 번째 프라미스가 거부되면서 Promise.all 전체가 거부되고, .catch가 실행됩니다.
거부 에러는 Promise.all 전체의 결과가 됩니다.
Promise.all([
new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
new Promise((resolve, reject) => setTimeout(() => reject(new Error("에러 발생!")), 2000)),
new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).catch(alert); // Error: 에러 발생!
Promise.allSettled()
Promise.all은 프라미스가 하나라도 거절되면 전체를 거절합니다.
반면, Promise.allSettled는 모든 프라미스가 처리될 때까지 기다립니다. 반환되는 배열은 다음과 같은 요소를 갖습니다.
✅ 응답이 성공할 경우 – {status:"fulfilled", value:result}
❌ 에러가 발생한 경우 – {status:"rejected", reason:error}
fetch를 사용해 여러 사람의 정보를 가져오고 있다고 해봅시다.
여러 요청 중 하나가 실패해도 다른 요청 결과는 여전히 필요합니다.
이럴 때 Promise.allSettled를 사용할 수 있습니다.
let urls = [
'https://api.github.com/users/iliakan',
'https://api.github.com/users/Violet-Bora-Lee',
'https://no-such-url'
];
Promise.allSettled(urls.map(url => fetch(url)))
.then(results => {
results.forEach((result, num) => {
if (result.status == "fulfilled") {
alert(`${urls[num]}: ${result.value.status}`);
}
if (result.status == "rejected") {
alert(`${urls[num]}: ${result.reason}`);
}
});
});
// results 값은 다음과 같습니다.
[
{status: 'fulfilled', value: ...응답...},
{status: 'fulfilled', value: ...응답...},
{status: 'rejected', reason: ...에러 객체...}
]
Promise.prototype.race()
Promise.race는 Promise.all과 비슷합니다. 다만 가장 먼저 처리되는 프라미스의 결과(혹은 에러)를 반환합니다.
let promise = Promise.all([...promises...]);
Promise.race([
new Promise((resolve, reject) => setTimeout(() => resolve(1), 1000)),
new Promise((resolve, reject) => setTimeout(() => reject(new Error("에러 발생!")), 2000)),
new Promise((resolve, reject) => setTimeout(() => resolve(3), 3000))
]).then(alert); // 1
첫 번째 프라미스가 가장 빨리 처리상태가 되기 때문에 첫 번째 프라미스의 결과가 result 값이 됩니다.
이렇게 Promise.race를 사용하면 '경주(race)의 승자’가 나타난 순간 다른 프라미스의 결과 또는 에러는 무시됩니다.
'JavaScript' 카테고리의 다른 글
[JavaScript - 25] URLSearchParams (0) | 2023.08.24 |
---|---|
[JavaScript - 24] async / await (0) | 2023.01.26 |
[JavaScript - 22] Promise.prototype.then(), catch(), finally() (0) | 2023.01.12 |
[JavaScript - 21] Promise (0) | 2023.01.11 |
[JavaScript - 20] 타이머 API (0) | 2023.01.11 |