Sunday, May 12, 2024
 Popular · Latest · Hot · Upcoming
87
rated 0 times [  89] [ 2]  / answers: 1 / hits: 65522  / 12 Years ago, sun, august 19, 2012, 12:00:00

I'm using the Node.JS driver for MongoDB, and I'd like to perform a synchronous query, like such:



function getAThing()
{
var db = new mongo.Db(mydatabase, server, {});

db.open(function(err, db)
{
db.authenticate(myuser, mypassword, function(err, success)
{
if (success)
{
db.collection(Things, function(err, collection)
{
collection.findOne({ name : bob}, function(err, thing)
{
return thing;
});
});
}
});
});
}


The problem is, db.open is an asychronous call (it doesn't block), so the getAThing returns undefined and I want it to return the results of the query. I'm sure I could some sort of blocking mechanism, but I'd like to know the right way to do something like this.


More From » node.js

 Answers
7

There's no way to make this synchronous w/o some sort of terrible hack. The right way is to have getAThing accept a callback function as a parameter and then call that function once thing is available.



function getAThing(callback)
{
var db = new mongo.Db(mydatabase, server, {});

db.open(function(err, db)
{
db.authenticate(myuser, mypassword, function(err, success)
{
if (success)
{
db.collection(Things, function(err, collection)
{
collection.findOne({ name : bob}, function(err, thing)
{
db.close();
callback(err, thing);
});
});
}
});
});
}


Node 7.6+ Update



async/await now provides a way of coding in a synchronous style when using asynchronous APIs that return promises (like the native MongoDB driver does).



Using this approach, the above method can be written as:



async function getAThing() {
let db = await mongodb.MongoClient.connect('mongodb://server/mydatabase');
if (await db.authenticate(myuser, mypassword)) {
let thing = await db.collection(Things).findOne({ name: bob });
await db.close();
return thing;
}
}


Which you can then call from another async function as let thing = await getAThing();.



However, it's worth noting that MongoClient provides a connection pool, so you shouldn't be opening and closing it within this method. Instead, call MongoClient.connect during your app startup and then simplify your method to:



async function getAThing() {
return db.collection(Things).findOne({ name: bob });
}


Note that we don't call await within the method, instead directly returning the promise that's returned by findOne.


[#83545] Friday, August 17, 2012, 12 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
rocky

Total Points: 316
Total Questions: 108
Total Answers: 110

Location: Mali
Member since Sat, Feb 12, 2022
2 Years ago
;