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를 사용하면 됩니다. => 차례가 보장되지 않으나 속도 빠름(병렬처리)
참고한 글)
'Programming Language > 🟨 Javascript' 카테고리의 다른 글
__proto__, Object.hasOwnProperty (0) | 2020.10.31 |
---|---|
ES6) Map & Set + swapping Map with Object (0) | 2020.10.26 |
ES6 제너레이터, 무한 개념 구현하기 (0) | 2020.08.15 |
Vanilla js로 fullpage.js 구현하기 (0) | 2020.08.02 |
클로저와 클로저를 활용한 private 변수, getter/setter (0) | 2020.07.16 |