[Javascript] async/await와 forEach(), map()

박기영·2023년 6월 22일
0

Javascript

목록 보기
44/45
post-custom-banner

여러 개의 API 통신을 진행할 필요가 있어서 Promise.all()을 사용했다.
비동기 통신을 위해 async/await도 사용했다.
그런데, 여러 개의 Promise를 처리하기 위해 forEach를 썼더니 비정상적인 동작을 했다.
map으로 변경했더니 이번엔 잘 동작한다!
왜 이런 일이 발생하는걸까?

문제 상황

// 비정상 작동

const response = await Promise.all([
  fetch("https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Alcoholic"),
  fetch(
    "https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Non_Alcoholic"
  ),
  fetch(
    "https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Optional_Alcohol"
  ),
]);

const data = await Promise.all(
  response.forEach(async (r) => {
    const json = await r.json();
    wholeCocktail.push(...json.drinks);
  })
);

Promise.all()을 통해 fetch를 진행한 것을 비동기적으로 처리하기 위한 코드이다.
비동기적으로 동작할 것만 같은 이 코드는 전혀 다르게 동작한다.
이 코드는...동기적으로 동작한다.

forEach()가 안되는 이유

그럼 왜 forEach에서 async/await를 사용하면 의도대로 동작하지 않는걸까?

forEach() expects a synchronous function — it does not wait for promises. Make sure you are aware of the implications while using promises (or async functions) as forEach callbacks.
- MDN docs -

forEach()는 동기적으로 동작하기 때문에, promise를 기다려주지 않는다고한다.
그렇기 때문에 async/await를 걸어봐도 전혀 효과가 없었던 것이다!

for of(), map()을 사용하자

forEach()는 비동기 처리가 불가능하기 때문에 Promise, async/await를 사용하는 상황이라면
다른 방법을 찾아야한다.

보통 for of(), map()을 많이들 사용하신다.
이 방법들은 Pormise, async/awiat의 사용이 가능하고, 비동기 처리도 가능하다!
필자는 map()을 사용하는 것으로 했다.

// 정상 작동

const response = await Promise.all([
  fetch("https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Alcoholic"),
  fetch(
    "https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Non_Alcoholic"
  ),
  fetch(
    "https://www.thecocktaildb.com/api/json/v1/1/filter.php?a=Optional_Alcohol"
  ),
]);

const data = await Promise.all(
  response.map(async (r) => {
     const json = await r.json();
     wholeCocktail.push(...json.drinks);
     return json.drinks;
   })
);

참고 자료

stackoverflow 질문글 1
stackoverflow 질문글 2
stackoverflow 질문글 3
hackmamba 게시글
forEach() - MDN docs
constructionsite님 블로그
jha0402님 블로그

profile
나를 믿는 사람들을, 실망시키지 않도록
post-custom-banner

0개의 댓글