개발자

자바스크립트 forEach 와 async await 을 같이 사용하면 안되는건가요?

2023년 05월 19일조회 1,502

최근에 받은 코드 리뷰에서 forEach 와 async await 을 같이 사용할 경우 문제가 발생할 수 있다는 피드벡을 받았습니다. 코드를 돌려 보았을 때는 크게 문제 없어보이는데 어떤 문제가 있는지 알려주실수 있나요 ? 만약 다음 코드에서 forEach 를 사용하면 안된다면 어떤 문법을 사용해야 하는지도 알려주세요. 사용 가능한 for 문이 너무 많아서 혼란스러워요 ㅠㅠ

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.
profile picture
익명님의 질문

답변 7

인기 답변

강병진님의 프로필 사진

forEach는 비동기 작업을 지원하지 않고, 프로미스가 resolve 될 때까지 기다리지 않고 다음 iteration으로 넘어가기 때문에 async/await와 같이 사용할 수 없습니다.

1

인기 답변

손정현님의 프로필 사진

안녕하세요! forEach는 비동기 작업이 완료될때까지 기다리지 않습니다. 비동기 요청 순서가 상관없다면 promise.all, 각각의 요청을 기다릴 필요가 있다면 for await of 사용하시면 될것 같아요! - https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/for-await...of - https://velog.io/@hiro2474/understandfor-await-of

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async function fetchAllComments() {
  const comments = [];

  const pages = await fetchPages();
  
  for await (const page of pages) {
         const comment = await fetchComment(page);
    comments.push(...comment);

         console.log(comment);
  };

  return comments;
}
엄홍재님의 프로필 사진

예전에 비슷한 질문을 보았던 기억이 있어서 찾아왔습니다! 해당 질문과 답변 참고해 보세요! https://careerly.co.kr/qnas/1879

강성호님의 프로필 사진

for of 쓰고 아래부분에 await 쓰시면 됩니다

이영준님의 프로필 사진

fetchAllComments 호출 결과를 바로 찍어보면 알겁니다 객체기 때문에 나중에 배열에 push가 되겠지만 배열을 사용하는 시점에 따라 달라질 수 있습니다. await forEach가 되는게 아닌 이상 forEach 내부 함수가 완료되기전에 return 되어버림

로이님의 프로필 사진

그래서 저같은 경우엔 map 메서드를 사용합니다.

커리어리 AI 봇님의 프로필 사진

JavaScript의 'forEach' 메소드와 'async/await'를 함께 사용하는 것은 주의가 필요합니다. 이는 비동기적인 동작을 제대로 처리하지 못할 수 있기 때문입니다. 'forEach' 메소드는 콜백 함수를 동기적으로 실행하며, 비동기 작업을 기다리지 않고 다음 요소로 넘어가게 됩니다. 따라서 'forEach' 내부에서 'async/await'를 사용하더라도 비동기 작업이 순서대로 처리되지 않고 병렬적으로 실행될 가능성이 있습니다. 이로 인해 예상치 못한 동작이 발생할 수 있습니다. 위의 코드에서도 'pages.forEach' 내부의 콜백 함수가 비동기 함수인데, 이 부분에서 발생할 수 있는 문제는 다음과 같습니다: 1. 'forEach'의 콜백 함수는 비동기로 실행되므로 'forEach' 자체의 동작이 완료되기 전에 'return comments;' 문이 실행될 수 있습니다. 따라서 'comments' 배열이 비어있는 상태로 반환될 수 있습니다. 2. 'forEach'의 각 이터레이션에서 비동기 작업이 병렬로 실행되므로, 'console.log(comment);' 문이 실행되는 순서가 예상과 다를 수 있습니다. 이러한 문제를 해결하기 위해서는 'forEach' 대신에 'for...of' 루프나 'for' 루프를 사용하여 요소를 순차적으로 처리하는 것이 좋습니다. 아래는 'for...of' 루프를 사용한 수정된 코드 예시입니다: 이 코드에서 'for...of' 루프는 'await' 키워드를 기다리면서 비동기 작업을 순차적으로 처리합니다. 이를 통해 예상한 대로 비동기 작업이 실행되고 결과가 수집됩니다. 따라서, 'forEach'와 'async/await'를 함께 사용하지 않고 'for...of' 루프나 'for' 루프를 사용하여 비동기 작업을 순차적으로 처리하는 것이 좋습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
async function fetchAllComments() {
  const comments = [];

  const pages = await fetchPages();

  for (const page of pages) {
    const comment = await fetchComment(page);
    comments.push(...comment);

    console.log(comment);
  }

  return comments;
}

커리어리 AI 봇의 답변을 평가해 주세요!

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

비슷한 질문 1

Q. [javascript]array에 push가 안됩니다.

배열에 원하는 데이터를 순서대로 가져온 후 배열에 넣고 싶은데 배열에 push가 되지 않아요.. console.log(info)는 데이터가 잘 나오는데 userInfo는 빈 배열 입니다. 아래 코드 첨부합니다.

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. - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach MDN 문서에 보면 forEach는 promise를 기다리지 않는다고 나옵니다. 그래서 API요청을 하는동안 이미 console.log(userProfiles)가 먼저 동작해서 []가 나옵니다. forEach안에서 console.log(info)를 실행해보면 [] 이후에 나오는 것을 확인할 수 있습니다. 해결하기 위해서는 이 링크를 참고해 보세요! https://constructionsite.tistory.com/43

이 질문 바로 가기

목록으로
키워드로 질문 모아보기

실무, 커리어 고민이 있다면

새로운 질문 올리기

지금 가입하면 모든 질문의 답변을 볼 수 있어요!