node.js에서 async모듈이 제대로 작동하지 않습니다.

조회수 1732회

pagination을 만들고 있습니다. 쿼리스트링으로 page를 입력받고 그에 맞게 mongoose로 DB를 불러와서 view로 던져주는 코드를 만들고 있습니다.

var page = req.query.page,
    perPage = 10;
if(page||page!=0||page!=1||typeof page != 'undefined') page=1;

async.waterfall([
    function(callback){
        ModA.find({}, {_id:0}).limit(perPage).skip(perPage * page).sort({
            name: 'asc'
        }).lean().exec(function(err, items){
            callback(null, items);
        });
    },
    function(items, callback){
        ModA.count().exec(function(err, count){
            callback(null, items, count);
        });
    }
], function(err, items, count){
    async.map(items, function(items, callback){
        Band.find({id : items.parent_id}, {name: 1, _id: 0}).lean().exec(function(err, band){
            items.parent_id = band[0].name;
            console.log(items.parent_id);    // 확인지점 A
        });
        callback(err, items);
    },function(err, items){
            console.log('async.map 결과;')    //  확인지점 B
            for(ind in items){
                console.log(items[ind].parent_id);
            }
        res.render('reg_product', {
            items: items,
            page: page,
            pages: count / perPage
        });
    });
});

쉽게 설명하자면 이 코드는 이렇습니다.

ModA에서 조건(page)에 맞는 document를 items 배열로 받아서 callback으로 넘김
--> ModA의 document 갯수를 count로 받아서 items와 같이 다음 callback으로 넘김
--> 마지막 결과 function에서 async.map을 한번 더 실행, items.parent_id로 Band collection에서 값을 참조해와서 갱신함
--> map.async 결과 function에서 res.render로 전달받은 값들과 함께 응답을 보냄

문제는 items.parent_id를 확인해보니 일부만 갱신이 되었더라는 겁니다(갱신 전 값은 정수고 새로 갱신되는 값은 문자열이라서 비교가 쉽습니다.)
그때그때 갱신된 갯수가 다른걸 보니 비동기 문제인것 같긴 한데 async.map, mapSeries, each, forEachOf 다 해봐도 마찬가지입니다.

게다가 디버깅을 위해서 확인지점 A, B에서 items.parent_id를 출력하도록 해보니 A지점에서는 확실히 갱신이 되었는데 B지점에서는 또 정수값들이 나오고 있고 게다가 표기되는 순서도 B가 먼저 나오고 A가 나오고 있습니다.

왜 그런지, 어떻게 해결가능한지 정말정말정말 궁금합니다. 자비로운 답변 부탁드립니다..

1 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    mongoose는 안써봤지만.. 흐름상 async.map 안에서 callback 호출하는 부분을 확인지점A와 같은 블럭에 두어야하지 않을까요?

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 해결된것 같습니다! 감사합니다 ㅎㅎ map은 forEach랑 비슷한 느낌이라 이것도 loop가 끝나면 callback을 호출해야 하지 않을까 하고 빼놨는데 생각과는 다르네요 Snark 2016.6.23 01:31

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)