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


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

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으로 보내주는 작업인데 원래의 배열로는

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

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

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

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

  • 2016년 05월 04일에 작성됨
    AWS, node.js, socket.io, mongoDB

조회수 145


1 답변


좋아요
2
싫어요
채택취소하기

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

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

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

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

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

Async

  • 2016년 05월 04일에 작성됨
    프로그래밍 언어를 좋아하는 프로그래머

  • 좋은 답변 항상 감사드립니다!!!    KimTaesik   2016.5.4 15:34     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close