Javascript node.js应用程序-如何连接到mongodb和;“分享”;通过包含连接?

Javascript node.js应用程序-如何连接到mongodb和;“分享”;通过包含连接?,javascript,node.js,mongodb,asynchronous,jasmine,Javascript,Node.js,Mongodb,Asynchronous,Jasmine,背景信息 我正在尝试我的第一个node.js API/应用程序。作为学习练习,我尝试创建一些测试用例,首先删除表中的所有记录,插入3条特定记录,然后查询这3条记录 代码 以下是我拼凑的代码: 问题 正如您从代码中看到的,我试图将数据库连接逻辑放在dbSession.js文件中并传递它 我可以通过执行以下操作来启动http服务器: dev@devbox:~/nimble_node$ sudo nodejs src/backend/index.js Server started and list

背景信息

我正在尝试我的第一个node.js API/应用程序。作为学习练习,我尝试创建一些测试用例,首先删除表中的所有记录,插入3条特定记录,然后查询这3条记录

代码

以下是我拼凑的代码:

问题

正如您从代码中看到的,我试图将数据库连接逻辑放在dbSession.js文件中并传递它

我可以通过执行以下操作来启动http服务器:

dev@devbox:~/nimble_node$ sudo nodejs src/backend/index.js 
Server started and listening on port: 8080
Database connection successful
但是,当我尝试运行jasmine测试时,它失败并出现以下错误:

F

Failures:

  1) The API should respond to a GET request at /api/widgets/
   Message:
     TypeError: Object #<MongoClient> has no method 'collection'
   Stacktrace:
     TypeError: Object #<MongoClient> has no method 'collection'
    at resetDatabase (/home/dev/nimble_node/spec/resetDatabase.js:6:29)
    at /home/dev/nimble_node/spec/e2e/apiSpec.js:23:25
    at /home/dev/nimble_node/node_modules/async/lib/async.js:683:13
    at iterate (/home/dev/nimble_node/node_modules/async/lib/async.js:260:13)
    at async.forEachOfSeries.async.eachOfSeries (/home/dev/nimble_node/node_modules/async/lib/async.js:279:9)
    at _parallel (/home/dev/nimble_node/node_modules/async/lib/async.js:682:9)
    at Object.async.series (/home/dev/nimble_node/node_modules/async/lib/async.js:704:9)
    at null.<anonymous> (/home/dev/nimble_node/spec/e2e/apiSpec.js:19:9)
    at null.<anonymous> (/home/dev/nimble_node/node_modules/jasmine-node/lib/jasmine-node/async-callback.js:45:37)

Finished in 0.01 seconds
1 test, 1 assertion, 1 failure, 0 skipped


Database connection successful
在错误出现后,我得到了“databaseconnectionsuccessful”消息,我认为发生的情况是,当测试请求dbSession库时,数据库还没有完成连接代码的运行。因此,我无法获取集合对象

我目前正在阅读mongodb在线手册,看看是否能找到一些关于如何进行类似操作的提示。 如有任何建议或建议,将不胜感激

编辑1

为了证明MongoClient对象上存在一个收集方法,我将dbSession.js代码更改为如下所示:

'use strict';

var DBWrapper = require('mongodb').MongoClient;
var dbWrapper = new DBWrapper;
dbWrapper.connect("mongodb://localhost:27017/test", function(err, db) {
        if (!err) {
                console.log("Database connection successful");
                dbWrapper = db;
                var collection = dbWrapper.collection('widgets');
                console.log('just created a collection...');
        }
});
module.exports = dbWrapper;
现在,当我启动http服务器(index.js)时,请注意以下消息:

dev@devbox:~/nimble_node$ sudo nodejs src/backend/index.js 
Server started and listening on port: 8080
Database connection successful
just created a collection...

这可能是一个异步问题

您在dbSessionjs中的代码

dbWrapper.connect("mongodb://localhost:27017/test", function(err, db) {
        if (!err) {
                console.log("Database connection successful");
                dbWrapper = db;
        }
});
module.exports = dbWrapper;
在dbWrapper异步启动连接,但立即导出dbWrapper,然后将其导入resetDatabase。因此,是的,当您在resetDatabase中调用异步函数时,connect函数可能尚未从异步函数返回(这是日志所建议的,因为错误出现在成功日志之前)

您可以在dbWrapper.connect()返回后添加回调,以便实际上只能在连接完成时使用dbWrapper

(对于sqlite,这可能不会发生,因为它在命令行上访问DB的速度更快)

这可能不是你的问题,但看起来像候选人

编辑:这里有一个可能的回调示例,但请注意,这取决于您需要做什么,因此有很多不同的解决方案。关键是在完成初始化后调用回调函数

另一种解决方案可以是简单地等待和/或轮询(例如,chcke变量“initialized”)


有趣的是,尽管我从未遇到过这个问题,尽管我通常使用类似于您的代码。我猜这是因为通常情况下,我会将DB初始化放在顶部,然后必须对节点应用程序进行大量初始化,这会给应用程序足够的时间从连接调用返回…

这可能是一个异步问题

您在dbSessionjs中的代码

dbWrapper.connect("mongodb://localhost:27017/test", function(err, db) {
        if (!err) {
                console.log("Database connection successful");
                dbWrapper = db;
        }
});
module.exports = dbWrapper;
在dbWrapper异步启动连接,但立即导出dbWrapper,然后将其导入resetDatabase。因此,是的,当您在resetDatabase中调用异步函数时,connect函数可能尚未从异步函数返回(这是日志所建议的,因为错误出现在成功日志之前)

您可以在dbWrapper.connect()返回后添加回调,以便实际上只能在连接完成时使用dbWrapper

(对于sqlite,这可能不会发生,因为它在命令行上访问DB的速度更快)

这可能不是你的问题,但看起来像候选人

编辑:这里有一个可能的回调示例,但请注意,这取决于您需要做什么,因此有很多不同的解决方案。关键是在完成初始化后调用回调函数

另一种解决方案可以是简单地等待和/或轮询(例如,chcke变量“initialized”)


有趣的是,尽管我从未遇到过这个问题,尽管我通常使用类似于您的代码。我猜这是因为通常情况下,我会将DB初始化放在顶部,然后必须对node应用程序进行大量初始化,这会给应用程序足够的时间从connect调用返回….

您是否遵循特定的教程?错误是说MongoClient对象没有收集方法,因此原因可能是我正在学习《节点工匠手册》中的教程。但是他们的例子(我做了,而且它是有效的)是针对sqlite的。我现在正在尝试将其改编为mongodb。mongo客户端对象确实有一个收集方法。。。但我认为这是一个时间问题。通过在数据库连接后立即创建一个集合对象,我已经证明了存在一个集合对象。请参见编辑1您是否遵循特定教程?错误是说MongoClient对象没有收集方法,因此原因可能是我正在学习《节点工匠手册》中的教程。但是他们的例子(我做了,而且它是有效的)是针对sqlite的。我现在正在尝试将其改编为mongodb。mongo客户端对象确实有一个收集方法。。。但我认为这是一个时间问题。通过在数据库连接后立即创建一个集合对象,我已经证明了存在一个集合对象。请参见编辑1,您已经明确阐述了我怀疑的问题所在。这就是我在最初的问题中试图描述的,但你做得更好。不过,我需要的是一个“回调”的例子,你已经明确指出了我怀疑的问题所在。这就是我在最初的问题中试图描述的,但你做得更好。我需要的是一个“回调”的例子
'use strict';

var DBWrapper = require('mongodb').MongoClient;
var dbWrapper = new DBWrapper;

function doConnect(callback) {
  console.log("Initializing DB connection...");
  dbWrapper.connect("mongodb://localhost:27017/test", function(err, db) {
        if (!err) {
                console.log("Database connection successful");
                dbWrapper = db; 
                var collection = dbWrapper.collection('widgets');
                console.log('just created a collection...');
                console.log('calling callback...');
                callback(dbWrapper);
        } else {
          console.log("Error connectingi: " + err);
        }
  }); 
};

doConnect(function(correctDbWrapper) {
    //Now you can use the wrapper
  console.log("Inside callback, now consuming the dbWrapper");
  dbWrapper = correctDbWrapper;
  var collection = dbWrapper.collection('widgets');
});