node.js에서 데이터를 mongodb에서 불러와 socket.io로 전송하는데 순서가 꼬입니다.

조회수 1396회

전체 소스를 넣으면 길어질것 같아 일단 잘라내면서 수정을 해서 올렸습니다. 난잡해 보인다면 죄송합니다.

for(var index in room.messagelog){
    if(msg.type != 'data'){
            match = urlPattern.exec(msg.msg);
            if(match != null && match.length>1){
                var text = match[0];
                og(text, function(err, meta){
                io.sockets.to(socket.room).emit('message url', msg, meta);
                });
            }else{
                console.log('일반')
                io.sockets.to(socket.room).emit('message', msg);
            }
        }else{
     Data.findOne({'room_name':socket.room,'send_id':email, 'name':msg.msg },function(err, data){
                if(err) console.log(err);
                if(data != null){
                    console.log('데이터')
                io.sockets.to(socket.room).emit('data', data,.email,name);
                }
            }); 
        }
}

제목과 같이 room.messagelog를 순서대로 분류해서 socket으로 보내주는 작업인데 원래의 배열로는

데이터
일반
일반
일반
데이터
일반
일반
일반

이 순서대로 나와야 정상인데 돌려서 확인을 하면

일반
일반
일반
일반
일반
일반
일반
데이터
데이터

이런 순서로 나옵니다. 저로써는 어떻게해서 이렇게 되는지 이해가 되질 않습니다. 어떤게 문제이고 이 문제를 어떻게 처리해야 할까요?

1 답변

  • 좋아요

    2

    싫어요
    채택 취소하기

    순서가 보장되지 않는 이유는 Data.findOne 함수가 비동기로 동작하기 때문에 그렇습니다.

    반복문 진행 중에 findOne함수를 실행하는 라인에서 데이터를 가져올 때 까지 기다리지 않고 곧바로 다음 라인으로 진행이 되며 findOne함수에 2번째 인자로 전달된 콜백 함수가 언젠가 실행 됩니다.

    때문에 반복문에서 findOne함수를 타지 않는 부분이 먼저 실행되고, 상대적으로 느린 findOne함수에 등록된 콜백 함수가 나중에 실행된 것 입니다.

    노드에서는 대부분 api가 이런 비동기 형태를 가지기 때문에 비동기 코드에 대한 이해가 정확히 필요합니다.

    아래 모듈을 참고하시면 해결 가능할거라 생각됩니다.

    Async

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 좋은 답변 항상 감사드립니다!!! KimTaesik 2016.5.4 15:34

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

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

(ಠ_ಠ)
(ಠ‿ಠ)