【问题标题】:How to make asynchronous call to mongoDB inside Connect middleware?如何在 Connect 中间件中对 mongoDB 进行异步调用?
【发布时间】:2014-05-08 01:04:21
【问题描述】:

假设我有以下 Express/Connect 中间件:

    return function(req, res, next) {
        mongoose.connect(url, options);
        var Config = mongoose.model('Config', mongoose.Schema({
            field1: Boolean,
            field2: []
        }));

        Config.findOne({}, function (err, doc) {
                    if(!err) {
                       if(someCondition)
                        // some logic: send response and interrupt middleware chain
                        res.end('Some response');
                        else
                        next();
                    }
        }
};

问题是数据库调用是异步的。所以中间件函数在任何逻辑执行之前退出。 任务很简单:从 mongoDB 读取配置,如果某个字段值 = 'something" 发送响应,否则 - 继续中间件链。

所以,我现在有 2 个问题

  1. 有没有办法在中间件内部进行异步调用?
  2. 如果没有,是否有任何解决方法? (AFAIK,没有办法同步执行 db 调用)

【问题讨论】:

    标签: node.js mongodb asynchronous express middleware


    【解决方案1】:

    所以中间件函数在任何逻辑执行之前就退出了。

    是的,但这对于 node.js 异步代码是完全正常且 100% 可以的。这就是异步代码的工作原理。数据库调用完成后,控制流恢复,您可以发送响应或调用next()。这很好。

    有没有办法在中间件内部进行异步调用?

    是的,而且你的做法很好(减去下面列出的一些小警告)。

    如果没有,有什么解决方法吗?

    无需解决方法。这就是 node.js 的设计方式。 node.js 中的所有网络 I/O 都是异步的。

    一些小笔记

    • 确保在数据库回调函数逻辑的每个可能分支中发送响应或调用next():错误、someCondition 为真、someCondition 为假。如果您的任何逻辑最终会出现在不响应请求且不调用next() 的分支中,则请求将挂起,直到由于超时而失败。您上面的 sn-p 缺少您需要做的错误处理。
    • 将猫鼬连接调用移至应用程序启动时间。不要在每个请求上都连接。
    • 将您的猫鼬模型定义移出到单独的模块Config.js

    【讨论】:

    • 感谢您的回答!我不确定,但如果我们有几个(比如说 5 个中间件)在链中怎么办?我的中间件是第一个。如果我们的数据库很慢,查询从我的第一个中间件开始,然后可以在我的数据库查询完成之前执行第二个、第三个......中间件(并发送它们的响应)。这是不正确的,因为我的中间件应该禁止客户端并使用“某些条件”发送相应的响应。因此,如果“某些条件”,则不应执行第 2、第 3 等中间件。
    • “当 DB 调用完成时,控制流恢复” - 这是否意味着我的中间件会等到 DB 调用完成并且不会执行下一个中间件?
    • 中间件 2 在中间件 1 调用 next() 之前不会开始执行。它们都按顺序运行。当您调用next() 时,您是在说“我完成了,可以开始下一个中间件功能了”。
    猜你喜欢
    • 1970-01-01
    • 2016-07-11
    • 2011-01-11
    • 2018-07-07
    • 2019-08-07
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多