如何在Connect中间件内部对mongoDB进行异步调用?

时间:2014-03-28 14:03:35

标签: node.js mongodb asynchronous express middleware

假设我有以下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'发送响应,否则 - 继续中间件链。

所以,我现在有两个问题

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

1 个答案:

答案 0 :(得分:2)

  

因此,在执行任何逻辑之前,中间件函数会退出。

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

  

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

是的,你这样做的方式很好(减去下面列出的一些小警告)。

  

如果没有,是否有解决方法?

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

一些小笔记

  • 确保在数据库回调函数逻辑的每个可能分支中发送响应或调用next():error,someCondition为true,someCondition为false。如果您的任何逻辑可以在不响应请求的分支中结束并且不调用next(),则该请求将暂停,直到由于超时而失败。您上面的代码段缺少错误处理,您需要这样做。
  • 将您的mongoose connect调用移至应用程序启动时间。请勿连接每个请求。
  • 将您的猫鼬模型定义移至单独的模块Config.js