본문 바로가기

Node.js

Node.js Mysql2로 async/await 사용하기

728x90

푸핫을 개발하면서 리뷰별로 이미지 리스트를 못담는 이슈가 생겼다.

스프링처럼 Mybatis에 resultMap을 사용하면 쉽게 Collection에 넣을 수 있지만 node.js에서 mysql을 orm 없이 개발하다 보니 해결하는데 시간이 오래걸렸다.

 

기존에 mysql 미들웨어를 사용했고 소스는 아래와 같았다.

router.get('/api/review/list/:seq', (req, res) => {
    let sql = 리뷰 select 쿼리
            
    con.query(sql, (err, result) => {
        if(err){
            return res.status(500).send({error : 'database failure'});
        }

        const dataArray = new Array();
        for (var i = 0; i < result.length; i++) {
            var reviewseq = result[i].seq;
            var imageQuery = 이미지 select 쿼리
            var data = result[i];
            con.query(imageQuery, (err, imageResult) => {
                if(err){
                    console.log(err);
                    con.rollback();
                    return res.status(500).send({error : 'database failure'});
                }
                if(imageResult.length > 0){
                    data = Object.assign(data, {"imageList" : imageResult});
                    
                }
            });
            dataArray.push(data);
        }
        
        res.json(dataArray);
    });
});

 

리뷰리스트를 SELECT 한뒤 리뷰별로 다시 이미지 리스트를 SELECT해서 담아준뒤 res.json으로 넘겨줄 생각이었는데 async와 await를 아무리 써도 동기식으로 동작하지않아 이미지 리스트를 Object.assign 하기도전에 res.json으로 넘어가는서 응답데이터에는 이미지리스트가 비어져있는 문제가 생겼다.

 

검색으로 async/await가 적용되기 위해서는 mysql2 미들웨어를 사용해야 한다는걸 알았다.

 

npm install mysql2 --save

mysql2 설치 후 require("mysql2")로 수정해줬다.

mysql2로 변경되어도 기존 작성되있던 api들은 그대로 작동되었다.

 

수정된 소스는 아래와 같다.

router.get('/api/review/list/:seq', async (req, res) => {
    let sql = 리뷰 리스트 SELECT 쿼리

    const [reviews, fields] = await con.promise().query(sql);
    
    for(var i=0; i<reviews.length; i++){
        let imageSql = 리뷰 이미지 리스트 SELECT 쿼리
        let [images, fields2] = await con.promise().query(imageSql);
        reviews[i].imageList = images;
    }

    res.json(reviews);
    
});

mysql2에서 async/await를 사용해주기 위해서는 connector의promise()로 query()를 사용해야한다.

기존 mysql 처럼 콜백이 존재하는 query()를 promise().query()로 날리면 에러를 뱉기으니 주의해야한다.

 

 const [rows, fields] = await connector.primise().query(쿼리) 형태로 다중 쿼리를 사용할수 있는데

rows에는 select한 리스트가 담아오고 fields는 찍어보니 별 방대한 내용이 찍혀서 다음에 알아보기로 한다.

 

로직은 기존 소스와 동일하게 리뷰 리스트 SELECT > 리뷰별 이미지 리스트 SELECT > 응답 이다.

 

 

728x90