개발 기술/사소하지만 놓치기 쉬운 개발 지식

[JS/Eslint] 반복문에서 await를 쓰지말자(no-await-in-loop)

by GicoMomg (Lux) 2022. 8. 27.

이번 시간에는 eslint 룰 중 하나인, no-await-in-loop에 대해 알아보았다!


1. eslint룰, no-await-in-loop

1) 이 규칙은?

  • 반복문에서 await 사용을 막는 규칙이다.
  • 만약, 프로미스 간에 정해진 순서가 있는 경우 반복문에서 await를 쓸 수 있으나
  • 프로미스 간에 정해진 순서가 없는 경우 반복문에서 await를 쓰는 건 성능상 좋지 않다.
for (const person of people) {
  const response = await getPersonId(person);  // ❌
}

🤔 그럼 성능을 향상시키면서, (정해진 순서가 없는)여러 프로미스을 처리하고 싶다면 어떻게 해야할까?
Promise.all을 쓰자!


2) Promise.all로 처리하자!

(1) Promise.all이란?

  • Promise.all([promise1, promise2, …])은 여러 개의 프로미스를 병렬로 처리하는 함수이다.
  • 만약 여러 프로미스 중 하나라도 실패한다면, 에러를 띄운다.
Promise.all([promise1, promise2, …]);

(2) 실패한(reject) 프로미스가 없는 경우

  • 실패한 Promise가 없기에 Promise.all이 정상적으로 진행된다.
const promise1 = Promise.resolve(10);
const promise2 = 'hello';
const promise3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 1000, ['12', '11']);
});

const values = await Promise.all([promise1, promise2, promise3]);  
console.log(values); 
// [10, 'hello', ['12', '11']]

(3) 실패한(reject) 프로미스가 있는 경우

  • Promise.all에서 진행하는 프로미스 중 하나라도 reject(실패)가 발생시 오류가 발생한다.
const promise1 = Promise.resolve(10);   
const promise2 = 'hello';
const promise3 = new Promise((resolve, reject) => {
  setTimeout(reject, 1000, ['12', '11']);   // 실패 Promise
});

const values = await Promise.all([promise1, promise2, promise3]);
console.log(values); 



(4) 반복문 내에 await 제거해보기

🤔 처음에 소개한 예시에 Promise.all을 사용하면 어떻게 바뀔까?

// [수정 전] 반복문 내에서 await를 쓴 경우
for (const person of people) {
  const response = await getPersonId(person); // 수정할 지점
}
// [수정 후] promise.all 사용한 경우
const responses = [];
for (const url of people) {
  const person = getPersonId(person);  
  responses.push(person);              // 1. 프로미스를 responses에 저장
}

await Promise.all(responses);          // 2. responses를 Promise.all로 처리


🙂 이처럼 Promise.all을 사용하면 여러 프로미스를 처리할 수 있지만, 하나라도 실패하면 오류를 띄운다. 만약 프로미스의 실패와 상관없이 실행시키고 싶다면 Promise.allSettled도 살펴보자!

반응형

댓글