forEach문을 쓰면 비동기처리가 안된다.

Seungeun·2024년 6월 13일

백엔드 기초

목록 보기
3/3
post-thumbnail

문제

  1. 현재 주문 관련 API를 만드는 과정에서 1개의 post 요청에서 총 5개의 sql문을 INSERT하는 코드를 작성중이었다.
  2. 순서는 FK참조에 따라 이렇게 구성된다.
    배달주소테이블 삽입 > 주문테이블 삽입 > 주문당-책테이블 삽입 > 장바구니 제거
  3. 그런데 장바구니 제거에서 book_id가 null이라며 자꾸 오류가 나는 것이었다.
  4. aysnc와 await 다 잘 작성한 것 같은데 왜그러지 ???

원인

의심이 갔던 바로 한가지 forEach문!

        items.forEach(async(item)=>{
          let sql3 = `INSERT INTO orderedbooks (order_id, book_id, quantity) 
VALUES (?, 
(SELECT book_id FROM cartItems WHERE id = ?),
(SELECT quantity FROM cartItems WHERE id = ?));`;
          val3 = [order_id,item,item];
          result3 = await addData(sql3,val3,res)
        };
        }) 

반복문 중에 for of문이 있었기 때문에 코드를 for of으로 고쳐보았고

Array.forEach() vs for..of

해결

        for (const item of items) {
            let sql3 = `INSERT INTO orderedbooks (order_id, book_id, quantity) 
            VALUES (?, 
            (SELECT book_id FROM cartItems WHERE id = ?),
            (SELECT quantity FROM cartItems WHERE id = ?));`;
            val3 = [order_id,item,item];
            result3 = await addData(sql3,val3,res)
        };

결국 정상 작동!!!

생각

forEach문은 비동기 처리를 못하고 for in문은 비동기처리를 해주는데 왜 그런걸까??

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.

promise를 기다려주지 않는다고 한다.
또한,forEach의 콜백함수는 호출만 하고 반환은 기다리지 않기 때문에 거의 동시에 호출된다고 생각해보면 비동기가 적용되지 않는다.

참조: https://velog.io/@0709/forEach%EC%99%80-Promise.all

profile
Wonderland

0개의 댓글