2014-11-07 2 views
0

사용자가 이미 MongoDB에 있는지 여부를 반환하려고합니다. console.logcollection.find() 범위 내에서 실행하면 정확한 양 (0보다 큼)이 인쇄됩니다. 그러나 userExists이 호출되면 항상 false (0)을 반환합니다.내부 함수가 완료되기 전에 Nodejs 함수가 반환됩니다.

어떻게 값을 반환하기 전에 이러한 함수가 완료 될 때까지 기다릴 수 있습니까? jQuery의 $.Deffered()에 대해 읽었습니다.하지만이 점이 나에게 더러움을 느끼며 작동하지 않았습니다.

function userExists(db, uid){ 
    var collection = db.get('users'); 
    var ret = 0; 

    collection.find({"uid":uid},{},function(e,docs){ 
     ret = docs.length 
    }); 

    return ret > 0?true:false; 
} 
+2

중복 가능성 [Ajax 호출의 응답을 반환하는 방법?] (http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax- 전화) – vkurchatkin

답변

1

일부 언급했듯이 collection.find은 다음과 같습니다. ynchronous이므로 userExists (return ret > 0?true:false;이있는 행)의 다음 행에 도달하면 너무 이르므로 ret 값이 설정되지 않았습니다. collection.find에 대한 콜백 외부의 어느 곳에서든지 (그리고 그 함수가 차례로 호출하는 함수) 쿼리가 아직 발생하지 않았습니다.

쿼리가 끝날 때까지 userExists을 "일시 중지"할 수있는 방법이 없으므로 전체 접근 방식을 변경해야합니다. 필요한 것은 연속 패턴입니다. 이것은 콜백에서 collection.find의 결과로 무엇을하고 있는지를 의미합니다.

ret으로 무엇을하려는 것인지 알 수 없으므로 코드 구성 방법이 크게 변경 될 수 있습니다. 다음은 일반적인 아이디어를 줄 수있는 개요입니다.

function processResultAndDisplayToTheUser(ret) { 
    //everything that needs to happen after the value of ret is set 
    if (ret > 0) { 
     doSomething(); 
    } else { 
     doSomethingElse(); 
    } 
} 

function userExists(db, uid){ 
    var collection = db.get('users'); 

    //ret doesn't exist here 

    collection.find({"uid":uid}, {}, function(e,docs){ 
     var ret = docs.length; 

     //ret finally exists, so pass it to a function and use it 
     processResultAndDisplayToTheUser(ret); 
    }); 

    //ret doesn't exist here either 
} 

//ret still doesn't exist here 
+0

비동기 함수에 대한 많은 게시물에서 힌트를 얻었고 코드를 재구성했습니다. 잠깐 게시 할 예정입니다. –

0

collection.find은이 호출 할 수 있습니다 당신은 지금 콜백 함수

function userExists(db, uid,callback){ 
var collection = db.get('users'); 


    collection.find({"uid":uid},{},function(e,docs){ 

    callback(docs.length); 
    }); 

} 

를 전달할 수 있습니다

당신이 당신의 코드를 변경해야 즉시 반환하지 않는 비동기 방법이기 때문에 userExists 함수 :

 userExists(db, uid,function(ret){ 
           //do something here 

       }) 
+1

다른 대답을 보면 똑같은 실수를 범했습니다. 그것은 작동하지 않습니다. –

+0

내 대답을 편집했습니다 –

+0

좋아, 그게 지금 작동합니다. 'call'에 대한 호출에'docs.length'를 넘겨줌으로써'ret' 변수를 제거 할 수도 있습니다. –

1

나는 코드를 재구성하여 구조 조정을 마쳤습니다. addUpdateUser() 함수를 생성하고, 거기에서 카운트 한 다음 addUser() 또는 updateUser() 함수를 적절하게 실행했습니다.

addUpdateUser(db, { 
    "uid" : uid, 
}); 

function addUpdateUser(db, userInfo){ 
    var collection = db.get('users'); 

    collection.find({"uid":userInfo.uid},{},function(e,docs){ 
     if(docs.length > 0){ 
      updateUser(db, userInfo) 
     }else{ 
      addUser(db, userInfo) 
     } 
    }); 
} 
+0

나에게 잘 어울립니다. –

+0

왜 여기서'ret'를 사용하고 있습니까? 디자인에 여분의 것 같습니다. – t0mppa

+0

네 말이 맞아. 그것은 흔적이었다. 편집 됨. –

관련 문제