在Node.js中进行同步MongoDB查询的正确方法是什么? [英] What is the right way to make a synchronous MongoDB query in Node.js?

查看:195
本文介绍了在Node.js中进行同步MongoDB查询的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用MongoDB的Node.JS驱动程序,我想执行同步查询,例如:

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;
                    });
                });
            }
        });
    });
}

问题是,db.open是一个异步调用(它不是块),所以getAThing返回undefined,我希望它返回查询的结果。我确信我可以使用某种阻塞机制,但我想知道正确的方法来做这样的事情。

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.

推荐答案

没有办法让这种同步没有某种可怕的黑客攻击。正确的方法是让 getAThing 接受一个回调函数作为参数,然后一旦 thing 可用就调用该函数。

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);
                    });
                });
            }
        });
    });
}

节点7.6+更新

async / await 现在提供了一种使用同步样式进行编码的方法返回promises的异步API(比如本机MongoDB驱动程序)。

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;
    }
}

然后您可以从另一个<$ c $拨打电话c> async 函数为 let thing = await getAThing();

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

但是,值得注意的是 MongoClient 提供了一个连接池,所以你不应该在这个方法中打开和关闭它。而是在您的应用启动期间调用 MongoClient.connect ,然后将您的方法简化为:

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" });
}

请注意,我们不会致电 await ,而是直接返回由 findOne 返回的承诺。

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

这篇关于在Node.js中进行同步MongoDB查询的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆