当前位置: 首页 > 面试题库 >

在Node.js中进行同步MongoDB查询的正确方法是什么?

宗政功
2023-03-14
问题内容

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

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”,我希望它返回查询结果。我确定我可以使用某种阻止机制,但我想知道执行此类操作的正确方法。


问题答案:

没有办法使这种同步变得不可怕。正确的方法是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现在提供了一种使用返回承诺的异步API(例如本机MongoDB驱动程序那样)时的同步
样式 编码方式。

使用这种方法,上面的方法可以写成:

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方法中调用,而是直接返回由返回的promise findOne



 类似资料:
  • 以下是mongodb中的集合 当我询问 MongoDB返回结果集中具有"拥有":"笔记本电脑"的文档。 当我询问 结果仅显示数据字段中第一个匹配“TV”的文档 我如何查询获得汤姆拥有电视的所有3个文档,不包括笔记本电脑文档。预期结果 注意:在本例中,我只提到了数据字段中的4个文档,其中原始集合有50多个文档。对不起,我的英语很差:)。

  • null my Library的核心逻辑 客户将使用我们的库,他们将通过传递builder对象来调用它。然后,我们将通过使用对象构造一个URL,并通过执行该对象对该URL进行HTTP客户端调用,在将响应作为JSON字符串返回后,我们将通过创建对象将该JSON字符串按原样发送给客户。有些客户会调用,有些可能会调用方法,所以我需要在库中分别提供两个方法。 接口: 您将如何实现同步和异步方法给定上述标准

  • 那么,回到问题上来,鉴于微软建议不要在新的开发中使用WebRequest而是使用只提供异步API的HttpClient,我该怎么办呢? 这是我正在做的一些伪代码... 如何实现ProcessStuff()?

  • 问题内容: 据我所知,可以在一个单元内进行调试。 但是,我有多个单元格之间的函数调用。 例如, 我试过的 我试图在cell-1的第一行中设置。但是它甚至在执行单元2之前就立即进入调试模式。 我试图在代码之前添加该行。但是,代码永远运行,永不停止。 在ipython笔记本中设置断点的正确方法是什么? 问题答案: 使用 ipdb 通过安装 用法: 用于逐行执行和进入函数使用,并退出调试提示使用。 有关

  • 问题内容: 我不确定这是否是同步我的的正确方法。 我有一个 从函数传递过来的。 现在,我正在尝试使其同步。这是否正确同步了我的对象? 问题答案: 您要进行两次同步,这是没有意义的,可能会减慢代码的速度:在列表上进行迭代时所做的更改需要整个操作的同步,在这种情况下,使用Using 这样做是多余的(它创建了一个包装程序来同步各个操作)。 但是,由于您要完全清空列表,因此迭代删除第一个元素是最糟糕的方法

  • 问题内容: 我最近从Angular转到了ReactJs。我正在使用jQuery进行API调用。我有一个API,该API返回要打印在列表中的随机用户列表。 我不确定如何编写我的API调用。最佳做法是什么? 我尝试了以下操作,但未得到任何输出。如果需要,我愿意实现替代API库。 下面是我的代码: 问题答案: 在这种情况下,您可以在中进行ajax调用,然后进行更新