2016-10-28 8 views
2

コールバック関数の範囲外でMongoClient findOneメソッド(rパラメータ)で取得したドキュメントを取得しようとしています。どうすればそれを達成できますか?コールバック関数スコープ外でMongoDBの結果を取得する

おそらく、Node.jsのMongoDBドライバを使用する私のアプローチは適切ではありません。

function loadUser(name) { 
    var result = {}; 

    function connection(err, db) { 
     assert.equal(null, err); 

     function callback(err, r) { 
      assert.equal(null, err); 
      db.close(); 
      result = r; // This does not work 
     } 
     db.collection('users').findOne({'user.name':name}, callback); 
    } 
    MongoClient.connect(url, connection); 
    return result; 
} 

答えて

1

MongoDBがそれを見つける前に戻ってきたので、結果は正しいオブジェクトではなく、割り当てられた値になります。

あなたのような何かをする必要があります。

function loadUser(name, cb) { 

    function connection(err, db) { 
     assert.equal(null, err); 

     function callback(err, r) { 
      assert.equal(null, err); 
      db.close(); 
      cb(err, r) // user 
     } 
     db.collection('users').findOne({'user.name':name}, callback); 
    } 
    MongoClient.connect(url, connection); 
    return; 
} 

そしてloadUserの使い方は次のようになります。

loadUser("example", function(err, user){ 
    console.log(user); 
    //Now do what you need with user 
}); 

はまた、あなたは常にユーザーを検索する場合、それだけオープンに良いだろうということに気づきます接続が一度終了し、アプリケーションが終了すると閉じます。

+0

感謝を!私は同じ結論に来る!今、私はこれが、それを使用するコードを分離して検索するコードを維持する正しい方法だと完全に確信しています。 – ecdani

0

「結果」変数は、loadUser関数のスコープ内に存在します。 MongoDBとの対話は非同期であるため、コールバックが起動するまでにloadUser関数は終了し、結果変数は存在しなくなります。

単純に結果変数をグローバルスコープに移動することができます。コールバックは「結果」が返ってくるのを待っていることを通知するように、あなたのコードを少しでも再構成したいと思うでしょう。

0

あなたが実行するために、条件付きタスクの多くを持っている場合、データは、特により保守流れになり非同期タスク処理するためにEventEmitterを使用することができます。

"use strict"; 

var MongoClient = require('mongodb').MongoClient; 
const EventEmitter = require('events'); 

class MyEmitter extends EventEmitter {} 

var url = 'mongodb://localhost:27017/myproject'; 

const myEmitter = new MyEmitter(); 

// connect to database 
var db = MongoClient.connect(url, function(err, dbs) { 

    if (err) { 
     console.log(err); 
     return; 
    } 
    console.log("Connected correctly to server"); 
    db = dbs; 
    //get user when connected 
    myEmitter.emit('getUser'); 
}); 

// getUser event 
myEmitter.on('getUser', function() { 

    db.collection('users').findOne({ 'user.name': "test" }, function callback(err, r) { 
     if (err) { 
      myEmitter.emit('processError', err); 
     } else { 
      myEmitter.emit('processResult', r); 
     } 
     db.close(); 
    }); 

}); 

// process result event 
myEmitter.on('processResult', function(result) { 
    //result received, process it here 
    console.log("result : " + result); 
}); 

// error event 
myEmitter.on('processError', function(err) { 
    //an error occured, process the error here 
    console.log("error : " + err); 
}); 
関連する問題