Promise all
- 우선 MDN의 Promise.all을 살펴보자 !!
Promise.all이란 ?
- Promise.all() 메서드는 MDN에서 이렇게 설명되어있다.
Promise.all() 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환한다.
주어진 프로미스 중 하나가 거부하는 경우, 첫 번째로 거절한 프로미스의 이유를 사용해 자신도 거부한다.
Promise.all() - JavaScript | MDN
Promise.all() 메서드는 순회 가능한 객체에 주어진 모든 프로미스가 이행한 후, 혹은 프로미스가 주어지지 않았을 때 이행하는 Promise를 반환합니다. 주어진 프로미스 중 하나가 거부하는 경우, 첫
developer.mozilla.org
- Promise.all은 파라미터로 배열을 받는다.
- 따라서, 모든 요소가 프로미스 객체이거나 프로미스 객체가 포함된 배열을 Promise.all()의 파라미터에 인자로 넣어준다.
- 이 때, Promise.all은 배열 안에 모든 요소가 성공적인지, 가장 먼저 실패한 요소가 있다면 실패한 요소의 실패 이유를 반환하게 된다.
const promiseResult = Promise.all([...]); | |
console.log(promiseResult); | |
// Promise { <state>: "fulfilled", <value>: Array[...] } |
Promise.all 활용 패턴
- 예시 코드
const getData = async () => { | |
const initData = []; | |
const tempPromise = []; | |
myData.items.forEach((examData) => { | |
const promise = client | |
.query({ query: FETCH_TEST, variables: { id: examData._id } }) | |
.then((res: any) => initData.push(res.data)); | |
tempPromise.push(promise); | |
}); | |
await Promise.all(tempPromise); | |
}; |
└ 위의 예시 코드는 forEach와 Promise.all을 이용하여 한번에 비동기처리를 하여 반복문이 중간에 비동기처리의 결과를 기다릴 필요가 없다.
여러 개의 비동기 처리를 병렬로 하기
- 여기서 여러 개의 비동기 처리는, 순서가 보장되지 않아도 되는 상황을 말한다.
- 예를 들어, "유저를 조회하고, 거기서 얻은 유저 아이디를 통해 찜하기 상품을 가져온다"와 같은 경우는 아니다.
- 순서와 무관한, "게시판 목록과 게시판 목록의 총개수를 조회한다"의 경우를 의미한다.
- 이렇게 순서와 무관한 비동기 작업을 병렬로 진행하기 위해 우선 async와 await을 이용했다.
async function display(text, time) { | |
return new Promise((resolved, rejected) => { | |
setTimeout( | |
() => | |
typeof text === "string" | |
? resolved("string") | |
: rejected("not string"), | |
time | |
); | |
}); | |
} |
┌ display라는 함수를 정의하였고, text와 time을 인자로 받고 있다.
├ 이 함수는 Promise를 리턴하고 있고, setTimeout을 통해 일정 시간 후에 실행되도록 하였다.
└ 이것을 실행해 보면 아래와 같이 된다.
console.time("소요시간"); | |
await display("hoon", 3000); | |
await display("junny", 2000); | |
await display("hoony", 1000); | |
console.timeEnd("소요시간); | |
// 소요시간: 6000ms |
┌ 각각의 함수가 실행된 후 다음 비동기 함수가 실행되므로 6초가 걸렸다.
└ 하지만, 이러한 경우 Promise.all을 사용한다면 훨씬 단축된 시간을 확인할 수 있다.
console.time("소요시간"); | |
await Promise.all([ | |
display("hoon", 3000), | |
display("junny", 2000), | |
display("hoony", 1000), | |
]); | |
console.timeEnd("소요시간"); | |
// 소요시간 : 3000ms |
따라서, async await과 Promise.all의 소요 시간을 비교해보면 아래와 같다.
소요 시간 | |
async await | 6초 |
Promise.all | 3초 |
└ async-await은 함수의 하나하나를 다 기다렸다가 하였고,
Promise.all은 병렬로 비동기 함수를 실행시켰기 때문에 이러한 결과가 나오게 되었다.

Promise.all의 장점 - Fail Test
- 비동기처리를 병렬적으로 해서 더 빠르게 처리할 수 있다는 장점이 있다.
- 하지만 이때만 장점이 있는게 아니라, 비동기 처리가 실패했을 경우에도 있다.
- Promise.all()은 중간에 어떤 함수가 에러가 났을 때 그 실패를 즉시 반환한다.
console.log("------------------"); | |
console.time("소요시간"); | |
try { | |
await display(1, 3000); | |
await display(2, 2000); | |
await display(3, 1000); | |
} catch (error) { | |
console.log(error); | |
} | |
console.timeEnd("소요시간"); | |
console.log("------------------"); | |
console.time("소요시간"); | |
try { | |
await Promise.all([display(1, 3000), display(2, 2000), dispaly(3, 1000)]); | |
} catch (error) { | |
console.log(error); | |
} | |
console.timeEnd("소요시간"); |

┌ 같은 비동기 처리를 하는 경우지만, 소요 시간이 전혀 다른 것을 볼 수 있다.
├ await으로 각각을 실행시켰을 경우 첫 번째 함수가 걸리는 시간인 3초를 다 채우고 에러를 반환한다.
├ 반면, Promise.all() 함수를 사용한 경우 비동기 함수가 병렬로 실행되기 때문에 실행 순서와는 상관없이
├ 가장 빨리 에러를 반환하는 함수의 시간을 기준으로 동작이 종료된다.
└ 따라서, 1초밖에 걸리지 않게 된다.
'React > 2022-上' 카테고리의 다른 글
Optimistic UI (0) | 2022.05.01 |
---|---|
LazyLoad vs Preload (0) | 2022.05.01 |
Observable (0) | 2022.05.01 |
token, XSS, CSRF (0) | 2022.04.24 |
Callback (0) | 2022.04.24 |