forEach 에서 Promise 사용시 주의 사항

forEach 에서 Promise await 기대하지말자.

const fn1 = async (val) => {
  await new Promise(resolve => setTimeout(resolve, 500));
  return val * 2;
};
const valXs = [];
console.time('forEach');
[1,2,3,4,5,6,7,8,9,10].forEach(async (val,idx)=>{
const valX = await fn1(val);
valXs.push(valX);
})
console.timeEnd('forEach');
console.log('valXs-1:',valXs.join(','));
setTimeout(()=>{ console.log('valXs-2:',valXs.join(',')); },1000)
=>
결과는
forEach: 0.12109375 ms
valXs-1: 
valXs-2: 2,4,6,8,10,12,14,16,18,20

forEach 는 콜백의 리턴을 안기다린다.
그냥 실행하고 끝
그래서 primise의 동작을 await 써도 동기적으로 보장할 수 없다.

================
for of 로 변경하면

const fn1 = async (val) => {
  await new Promise(resolve => setTimeout(resolve, 500));
  return val * 2;
};
const valXs = [];
console.time('for');
for(val of [1,2,3,4,5,6,7,8,9,10]){
const valX = await fn1(val);
valXs.push(valX);
}
console.timeEnd('for');
console.log('valXs-1:',valXs.join(','));
setTimeout(()=>{ console.log('valXs-2:',valXs.join(',')); },1000)
=>
for: 5084.041015625 ms
valXs-1: 2,4,6,8,10,12,14,16,18,20
valXs-2: 2,4,6,8,10,12,14,16,18,20
동작이 보장 된다.

=================-==========
PS
Q. forEach에서 setTimeout(()=>{ console.log('valXs-2:',valXs.join(',')); },1000) 에선 왜 결과 값이 나오나? 5초 기다리니깐 1초 후에 출력하는 결과는 비어있어야하지 않나?
A. forEach 는 응답을 기다리지 않는다. 즉 0.5초 걸릴 걸 한번에 10개 동작 시킨 것과 같다. 즉, 약 0.5초안에 배열에 값이 들어간다. 그래서 1초 후에 배열을 가져와보면 내용이 들어있다.
500 말고 1500 으로 바꾸면 빈 결과를 보게 될 것이다.
댓글
  • No Nickname
    No Comment
  • 권한이 없습니다.
    {{m_row.m_nick}}
    -
목록형 📷 갤러리형
제목
[기본형] HTML (with 부트스트랩5.3 , jquery 3.7, vue.js)
유용한 리눅스(LINUX) 명령어
[공지] 기술 게시판
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
2.10
2.11
2.12
2.13
2.14
2.15
2.16
2.17
2.18
2.19
2.20
2.21
2.22
2.23
2.24
2.25
2.26
2.27
2.28