2016-11-15 10 views
0

私は、次のコード(つまり、期待どおりに動作しません)している:node.js:コールバック関数の値を返す方法は?

var express = require('express') 
var app = express() 
var MongoClient = require('mongodb').MongoClient; 
var url = 'mongodb://localhost:27017/interviews'; 

app.get('/', function(req, res){ 
    var result = get_document(res); 
    res.send(result // show the results of get document in the browser //) 
    console.log("end"); 
}); 

app.listen(3000, function(req, res) { 
    console.log("Listening on port 3000"); 
}); 

function get_document() { 
    MongoClient.connect(url, function(err, db) { 
    var col = db.collection('myinterviews'); 
    var data = col.find().toArray(function(err, docs) { 
     db.close(); 
     return docs[0].name.toString(); // returns to the function that calls the callback 
    }); 
    }); 
} 

関数「get_documentは」「myinterviews」コレクションに保存されたドキュメントを返すことになっています。問題は、line 'return docs [0] ...'がapp.get(...)内の変数 'result'ではなく、col.find(コールバックを呼び出した関数)に戻ることです。

文書を「結果」変数に戻す方法を知っていますか?

答えて

1

約束のAPIを見てください。

"get_document"関数は、解決および拒否の関数コールバック(成功/失敗)とともに新しい約束を返すべきです。

だから、それは少しのようになります。

var express = require('express') 
var app = express() 
var MongoClient = require('mongodb').MongoClient; 
var url = 'mongodb://localhost:27017/interviews'; 

app.get('/', function(req, res){ 
var result = get_document(res).then(function (doc) { 
    res.send(doc); 
}); 
// show the results of get document in the browser //) 
console.log("end"); 
}); 

app.listen(3000, function(req, res) { 
    console.log("Listening on port 3000"); 
}); 

function get_document() { 

    return new Promise(

    function (resolve, reject) 
     MongoClient.connect(url, function(err, db) { 
     var col = db.collection('myinterviews'); 
     var data = col.find().toArray(function(err, docs) { 
     db.close(); 
     resolve(docs[0].name.toString()); // returns to the function that calls the callback 
    }); 
    }); 
); 
} 
+0

素晴らしい答えです。ありがとう。約束どおり - あなたはbluebird.promisify(bluebirdjs.com/docs/api/promise.promisify.html)が良いと思いませんか? – CrazySynthax

+0

イェップ、そうかもしれない。私はそれを使用していないので、私は経験に基づいてコメントすることはできません:)これをチェックしてください:http://softwareengineering.stackexchange.com/questions/278778/why-are-native-es6-promises-slower-and-more-memory-intensive-than-bluebird – Alex

1

あなたget_document関数は非同期で実行されます。 MongoClient.connect()への呼び出しには時間がかかることがあるため、すぐに戻ることはできません。あなたのデータベース呼び出しからの後の値を返すには、get_document関数にコールバックを渡す必要があります。だからこれは次のようになります:

var express = require('express') 
var app = express() 
var MongoClient = require('mongodb').MongoClient; 
var url = 'mongodb://localhost:27017/interviews'; 

app.get('/', function(req, res){ 
    var result = get_document(function(result) { 
     res.send(result); 
     console.log("end"); 
    }); 
}); 

app.listen(3000, function(req, res) { 
    console.log("Listening on port 3000"); 
}); 

function get_document(done) { 
    MongoClient.connect(url, function(err, db) { 
    var col = db.collection('myinterviews'); 
    var data = col.find().toArray(function(err, docs) { 
     db.close(); 
     done(docs[0].name.toString()); // returns to the function that calls the callback 
    }); 
    }); 
} 
+1

また、Promises:https ://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise < - ここでそれらを読むことができます –

+1

偉大な答え。ありがとう。約束どおり - あなたはbluebird.promisify(http://bluebirdjs.com/docs/api/promise.promisify.html)が良いと思いませんか? – CrazySynthax

+0

確かに、私はブルーバードを使用していません。プロミスは常に私をラインで乗り越えることができたので、私は、ドキュメントを読んで、私の考えを伝えます:) –

関連する問題