Jak wspomniano w innej odpowiedzi, ten kod jest asynchroniczny, nie możesz po prostu zwrócić wartości, którą chcesz w dół łańcucha wywołań zwrotnych (funkcje zagnieżdżone). Musisz ujawnić jakiś interfejs, który pozwoli Ci zasygnalizować kod wywołujący, gdy masz pożądaną wartość (stąd oddzwanianie lub oddzwanianie).
W innej odpowiedzi znajduje się przykład wywołania zwrotnego, ale istnieje alternatywna opcja, którą zdecydowanie warto zbadać:obietnice.
Zamiast funkcji zwrotnej, którą wywołujesz z pożądanymi wynikami, moduł zwraca obietnicę, która może wprowadzić dwa stany, spełniony lub odrzucony. Kod wywołujący czeka na obietnicę wejścia w jeden z tych dwóch stanów, a gdy to zrobi, zostanie wywołana odpowiednia funkcja. Moduł wyzwala zmianę stanu przez resolve
ing lub reject
inż. W każdym razie, oto przykład użycia obietnic:
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);
});
Teraz, bardziej aktualne wersje sterownika mongodb node.js mają natywną obsługę obietnic, nie musisz wykonywać żadnej pracy, aby zawinąć wywołania zwrotne w obietnice, jak powyżej. To znacznie lepszy przykład, jeśli używasz aktualnego sterownika:
// 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);
});
Obietnice zapewniają doskonałą metodę asynchronicznego przepływu sterowania, gorąco polecam poświęcenie czasu na zapoznanie się z nimi.