是什么力量让在Node.js的一个同步的MongoDB查询的正确方法?(What is the ri

2019-06-17 19:24发布

我使用Node.js的驱动程序MongoDB的,我想执行同步查询,像这样的:

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返回“未定义”,我想它返回的查询结果。 我敢肯定,我可以某种阻挡机构的,但我想知道这样做的正确方法。

Answer 1:

有没有办法让这个同步W / O某种可怕的黑客。 正确的做法是有getAThing接受一个回调函数作为参数,然后调用该函数一次thing是可用的。

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现在提供使用返回的承诺(如本地的MongoDB驱动程序一样)异步API时在同步风格编码的一种方式。

使用这种方法,上述方法可以被写为:

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

然后你可以从另一个调用async功能let thing = await getAThing();

不过,值得注意的是, MongoClient提供了一个连接池,所以你不应该开在此方法中关闭它。 相反,调用MongoClient.connect您的应用程序启动时,然后简化您的方法:

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

请注意,我们不叫await的方法中,而不是直接返回多数民众赞成通过返回的承诺findOne



Answer 2:

EN 6(8+节点)

您可以利用异步/ AWAIT

await运营商暂停异步函数的执行,直到承诺解决和返回值。

这样,你的代码将在同步方式工作:

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



较早的解决方案 - 2013年6月)

现在蒙戈同步是可用的,这是为了使Node.js的一个同步的MongoDB查询的正确方法

我用这对是相同的。 你可以只写象下面同步方法:

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

注意:它依赖于节点纤维和一些问题,它有没有在Windows 8上。

编码愉快:)



Answer 3:

虽然它不是严格同步,模式我已经多次通过发现非常有用的方法是使用合作和promisify产量异步功能。 对于蒙戈,你可以把上面的:

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 => {

} );

这意味着:

  1. 你可以写“同步”般的代码与任何异步库
  2. 错误是从回调抛出,这意味着你不需要检查成功
  3. 您可以将结果作为承诺的任何其他部分的代码


文章来源: What is the right way to make a synchronous MongoDB query in Node.js?