別の回答で述べたように、このコードは非同期であり、コールバック(ネストされた関数)のチェーンの下で必要な値を単純に返すことはできません。必要な値を取得したら、呼び出し元のコードに信号を送ることができるインターフェイスを公開する必要があります(したがって、呼び出し元に戻すか、コールバックします)。
別の回答で提供されているコールバックの例がありますが、間違いなく検討する価値のある代替オプションがあります:promise。
モジュールは、目的の結果で呼び出すコールバック関数の代わりに、実行または拒否の2つの状態に入ることができるpromiseを返します。呼び出し元のコードは、Promiseがこれら2つの状態のいずれかに入るのを待ち、そのときに適切な関数が呼び出されます。モジュールはresolve
によって状態変化をトリガーします ingまたはreject
ing。とにかく、これがpromiseを使用した例です:
Db1.js:
// db1.js
var MongoClient = require('mongodb').MongoClient;
/*
node.js has native support for promises in recent versions.
If you are using an older version there are several libraries available:
bluebird, rsvp, Q. I'll use rsvp here as I'm familiar with it.
*/
var Promise = require('rsvp').Promise;
module.exports = {
FindinCol1: function() {
return new Promise(function(resolve, reject) {
MongoClient.connect('mongodb://localhost:27017/db1', function(err, db) {
if (err) {
reject(err);
} else {
resolve(db);
}
}
}).then(function(db) {
return new Promise(function(resolve, reject) {
var collection = db.collection('col1');
collection.find().toArray(function(err, items) {
if (err) {
reject(err);
} else {
console.log(items);
resolve(items);
}
});
});
});
}
};
// app.js
var db = require('./db1');
db.FindinCol1().then(function(items) {
console.info('The promise was fulfilled with items!', items);
}, function(err) {
console.error('The promise was rejected', err, err.stack);
});
現在、node.js mongodbドライバーの最新バージョンではpromiseがネイティブでサポートされているため、上記のようなpromiseでコールバックをラップするための作業を行う必要はありません。最新のドライバーを使用している場合、これははるかに良い例です:
// db1.js
var MongoClient = require('mongodb').MongoClient;
module.exports = {
FindinCol1: function() {
return MongoClient.connect('mongodb://localhost:27017/db1').then(function(db) {
var collection = db.collection('col1');
return collection.find().toArray();
}).then(function(items) {
console.log(items);
return items;
});
}
};
// app.js
var db = require('./db1');
db.FindinCol1().then(function(items) {
console.info('The promise was fulfilled with items!', items);
}, function(err) {
console.error('The promise was rejected', err, err.stack);
});
Promiseは、非同期制御フローの優れた方法を提供します。時間をかけてそれらに慣れることを強くお勧めします。