What is the right way to make a synchronous MongoDB query in Node.js?

后端 未结 3 1117
礼貌的吻别
礼貌的吻别 2020-11-29 01:50

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(\"mydata         


        
相关标签:
3条回答
  • 2020-11-29 02:20

    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.

    0 讨论(0)
  • 2020-11-29 02:23

    ES 6 (Node 8+)

    You can utilize async/await

    await operator pauses the execution of asynchronous function until the Promise is resolved and returns the value.

    This way your code will work in synchronous way:

    const query = MySchema.findOne({ name: /tester/gi });
    const userData = await query.exec();
    console.log(userData)
    



    Older Solution - June 2013 ;)

    Now the Mongo Sync is available, this is the right way to make a synchronous MongoDB query in Node.js.

    I am using this for the same. You can just write sync method like below:

    var Server = require("mongo-sync").Server;
    var server = new Server('127.0.0.1');
    var result = server.db("testdb").getCollection("testCollection").find().toArray();
    console.log(result);
    

    Note: Its dependent on the node-fiber and some issues are there with it on windows 8.

    Happy coding :)

    0 讨论(0)
  • 2020-11-29 02:32

    While it's not strictly synchronous, a pattern I've repeatedly adopted and found very useful is to use co and promisify yield on asynchronous functions. For mongo, you could rewrite the above:

    var query = co( function* () {
    
        var db = new mongo.Db("mydatabase", server, {});
        db = promisify.object( db );
        db = yield db.open();
    
        yield db.authenticate("myuser", "mypassword");
    
        var collection = yield db.collection("Things");
        return yield collection.findOne( { name : "bob"} );
    
    });
    
    query.then( result => {
    
    } ).catch( err => {
    
    } );
    

    This means:

    1. You can write "synchronous"-like code with any asynchronous library
    2. Errors are thrown from the callbacks, meaning you don't need the success check
    3. You can pass the result as a promise to any other piece of code
    0 讨论(0)
提交回复
热议问题