본문으로 바로가기

forEach 보통 이용하는 방법은 다음과 같습니다. map같은 경우도 마찬가지지요.

const items = ['item1', 'item2', 'item3'];
const copy = [];

items.forEach(function(item){
  copy.push(item);
});

console.log(copy)  //["item1", "item2", "item3"]

 

그런데 다음과 같은 코드에서는 subCommentList에 빈배열이 반환됩니다.

subComment = ["key1", "key2"]
const subCommentList = [];

subComment.forEach(async function (el) {
  let output;
  
  try {
    const subCom = await Comment.findById(el);
    output = subCom;
  } catch (err) {
    res.json({ foundSubComment: false, err: err.message });
  }
  subCommentList.push(output);
});

console.log(subCommentList); // [] 빈 배열

 

그 이유는 forEach에서 실행하는 함수가 (비동기라고 할지라도) 그것의 처리 결과를 기다려주지 않습니다. map, forEach와 같은 메서드의 callback을 async로 선언하면, 각 배열의 요소들을 await하게 되지만 map, forEach 그 자체는 await하지 않기 때문에 완전한 비동기처리가 이루어 지지는 않습니다.

 

따라서 이 경우에는 map/foreach 등에서 비동기 처리를 콜백으로 사용하기 위해서는 다르게 처리를 해줘야 합니다.

 

순차적으로 처리하고 싶다면 for 이나 for...of를 사용하셔야하고 => 차례가 보장되나 속도가 느림

병렬적으로 처리하고 싶다면 Promise.all를 사용하면 됩니다. => 차례가 보장되지 않으나 속도 빠름(병렬처리)

 

 

참고한 글)

 

 

배열에 비동기 작업을 실시할 때 알아두면 좋은 이야기들

프론트엔드 인턴 면접에서 비동기 작업 관련 질문 대답 못한 뒤 외양간 뚝딱뚝딱 고치는 이야기.

velog.io

 

[Async function] async/await 비동기 처리 :: 마이구미

이 글은 ES8(ECMA2017) 스펙에서 정의된 async/await 키워드를 다뤄본다. async/await 를 사용하기 위해서는 Promise 의 이해는 필요하다. 이 글에서는 다루지 않고, 오로지 async/await 에 초점을 맞춰 예제..

 

TS로 살펴보는 Promise + Promise.all 병렬처리

https://darrengwon.tistory.com/279 Promise 일반에 대한 내용은 위 포스트에서 이미 다뤘습니다. 여기서는 조금 더 자세하게 Promise를 다룰 것이며, TS를 사용할 예정입니다. 일반적으로 Promise를 타이핑할 때

darrengwon.tistory.com

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체