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) 명령어
[공지] 기술 게시판
4.26
4.27
4.28
4.29
4.30
5.1
5.2
5.3
5.4
5.5
5.7
5.8
5.9
5.10
5.13
5.14
5.15
5.16
5.17
5.18
5.19
5.20
5.21
5.22
5.23
5.24
5.25
5.26
5.27
5.28
5.29
5.30
5.31
6.1
6.2
6.3
6.4
6.5
6.6