简体   繁体   English

node.js应用程序-如何通过include连接到mongodb和“共享”连接?

[英]node.js application - how to connect to mongodb and “share” connection via an include?

Background Information 背景资料

I'm attempting my first node.js API/application. 我正在尝试我的第一个node.js API /应用程序。 As a learning exercise, I'm trying to create some test cases initially delete all records in a table, insert 3 specific records, and then query for those 3 records. 作为一项学习练习,我试图创建一些测试用例,首先删除表中的所有记录,插入3条特定记录,然后查询这3条记录。

Code

Here's the code I have cobbled together: 这是我拼凑的代码:

http://pastebin.com/duQQu3fm http://pastebin.com/duQQu3fm

Problem 问题

As you can see from the code, I'm trying to put the database connection logic in a dbSession.js file and pass it around. 从代码中可以看到,我正在尝试将数据库连接逻辑放在dbSession.js文件中并传递它。

I am able to start up the http server by doing the following: 我可以通过执行以下操作来启动http服务器:

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

However, when I try to run my jasmine tests, it fails with the following error: 但是,当我尝试运行茉莉花测试时,它失败并显示以下错误:

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

Line 6 of resetDatabase is: resetDatabase的第6行是:

 var collection = dbSession.collection('widgets');

Given that after the error appears, I get the "Database connection successful" message, I think what's happening is that when the tests request the dbSession library, the database hasn't finished running the code to connect. 鉴于出现错误后,我收到“数据库连接成功”消息,我认为发生的事情是,当测试请求dbSession库时,数据库尚未完成运行代码的连接。 And therefore, I can't get the collection object. 因此,我无法获取集合对象。

I'm currently reading through the mongodb online manual to see if I can find some hints as to how to do something like this. 我目前正在阅读mongodb在线手册,以了解是否可以找到有关如何执行此类操作的提示。 Any suggestions or pointers would be appreciated. 任何建议或指示,将不胜感激。

EDIT 1 编辑1

To prove that there is a collection method on the MongoClient object, I changed the dbSession.js code to look like this: 为了证明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;

And now, when I start up the http server (index.js), notice the messages: 现在,当我启动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...

It could be an async issue. 这可能是一个异步问题。

Your code in dbSessionjs 您在dbSessionjs中的代码

dbWrapper.connect("mongodb://localhost:27017/test", function(err, db) {
        if (!err) {
                console.log("Database connection successful");
                dbWrapper = db;
        }
});
module.exports = dbWrapper;

Starts the connection at dbWrapper asynchronously , but exports dbWrapper right away, which is then imported in resetDatabase. 异步启动dbWrapper的连接,但立即导出dbWrapper,然后将其导入resetDatabase中。 Thus yes, the connect function may have not yet returned from the async function when you call it in resetDatabase (and is what the log suggests,as the error appears before the success log). 因此,是的,当您在resetDatabase中调用connect函数时,它可能尚未从异步函数返回(这是日志所建议的,因为错误出现在成功日志之前)。

You could add a callback after dbWrapper.connect() returns, in order to actually only be able to use dbWrapper when the connection finished. 您可以在dbWrapper.connect()返回之后添加一个回调,以便实际上只能在连接完成后使用dbWrapper。

(With sqlite, this may not happen as it accesses the DB faster on the commandline). (使用sqlite时,这可能不会发生,因为它可以在命令行上更快地访问数据库)。

This may not be your problem but looks like a candidate. 这可能不是您的问题,但看起来像一个候选人。

EDIT: Here's a possible example for a callback, but please take note it depends on what you need to do so there are a lot of different solutions. 编辑:这是回调的可能示例,但是请注意,这取决于您需要执行的操作,因此有很多不同的解决方案。 The key is to call a callback function when you are done initializing. 关键是在完成初始化后调用回调函数。

Another solution could be to simply wait, and/or poll (eg chcke a variable 'initialized'). 另一个解决方案可能是简单地等待和/或轮询(例如,将变量“初始化”)。

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

It's interesting though I never ran into this issue, although I have generally used similar code like yours. 有趣的是,尽管我通常都使用过类似您的代码,但我从未遇到过这个问题。 I guess because normally I have this DB initialization right at the top, and then have to do lots of initializations on the node app, which gives the app time enough to return from the connect call.... 我猜是因为通常我在顶部有此数据库初始化,然后必须在节点应用程序上进行大量初始化,这使应用程序有足够的时间从连接调用中返回。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM