express4重用mongodb句柄

时间:2017-07-07 11:40:11

标签: node.js mongodb

我是javascript和nodejs编程的新手。我试图在快速框架中连接mongodb,但喜欢保持代码模块化。我写了下面的代码。我使用的是快速版本4.14.0和mongodb驱动程序2.2.27版本和nodejs v6.10.3

//app.js
var express = require('express');
var app = express();
var index = require('./routes/index');
app.use('/', index);
app.listen(3000);

//routes/index.js
var router = require('express').Router();
var anotherfile = require('../controllers/anotherfile');

router.get('/', function(req, res) {
        res.send('Connected');
});    
module.exports = router;

//controllers/db.js
var MongoClient = require('mongodb').MongoClient;
var connectionString = 'mongodb://user:password@127.0.0.1:27017/testdb';
var _db;

MongoClient.connect(connectionString, function(err, db) {
  if (err) {
    console.log('Error: ', err);
  } else {
    console.log('Connected!');
    _db = db;
    console.log("_db",_db);
  }
});

module.exports.getDb = function() {
  return _db;
}

//controllers/anotherfile.js
var connect = require('./db.js');
var db1 = connect.getDb();
console.log("print db1",db1);

我想从上面的代码中访问另一个文件中的db句柄。我在这里做错了什么?

2 个答案:

答案 0 :(得分:0)

为了保持代码模块化,您应该将数据库函数保存在单独的文件中,然后从 var $dataInputs; var $selectAll = $('#selectAll').change(function() { $dataInputs.prop('checked', this.checked) .closest('tr') .toggleClass("warning", this.checked); }); $dataInputs = $("input[type='checkbox']").not('#selectAll').change(function(e) { // toggle class on this row $(this).closest('tr').toggleClass("warning", this.checked); // adjust `selectAll` based on all rows selected or not $selectAll.prop('checked', function() { return $dataInputs.length === $dataInputs.filter(':checked').length; }); }); 的其他文件中访问这些函数。这样,您也可以将该数据库函数文件用于其他项目。

<强> mongoConfig.js

anotherfile.js

您在server.js中的代码。

<强> server.js

var express = require('express');
var router = express.Router();
module.exports = router;
var mongo = require('mongodb');
var uri = '<MongoDB server path>';

module.exports.insert = function(collectionName, json, callback) {
  mongo.MongoClient.connect(uri, function(err, db) {
    if (!err) {

    } else {

    }
  });
};

module.exports.retrieve = function(collectionName, json, callback) {
  mongo.MongoClient.connect(uri, function(err, db) {
    if (!err) {

    } else {

    }
  });
};

然后,

<强> anotherfile.js

var express = require('express');
var app = express();
var index = require('./routes/index');
app.use('/', index);
app.listen(3000);

//routes/index.js
var router = require('express').Router();
var anotherfile = require('../controllers/anotherfile');

router.get('/', function(req, res) {
    res.send('Connected');
});    

使用require将var Mongo = require('./mongoConfig');. Mongo.insert(); Mongo.retrieve(); 导入mongoConfig.js

答案 1 :(得分:0)

这基本上是经典的新JS开发人员与异步代码问题。

// When you require db.js, you're kicking off `MongoClient.connect`, which is
// an async function.
var connect = require('./db.js');

// On the very next line when you `getDb`, the connect function callback has not 
// happened yet, and db1 is undefined.
var db1 = connect.getDb(); //=> undefined

如果在连接功能完成后将getDb的执行推迟到,则应该可以正常工作。

setTimeout(function () {
  var db1 = connect.getDb(); //=> no longer undefined
}, 5000);

在快速应用中,您通常在路由中运行代码,这些代码是异步的。因此,在调用connect之后很久就会访问数据库,这将成为一个非问题(这就是为什么如果你谷歌你将会看到人们按照你尝试的方式进行操作)。

如果您想以不同的方式解决问题,您可能会认为MongoClient.connect在未通过回调时会返回一个承诺。这意味着你可以写一个非常简单的重写你的例子:

// db.js
var MongoClient = require('mongodb').MongoClient;
var connectionString = '...';
var connectPromise = MongoClient.connect(connectionString);

exports.getDb = function () {
  return connectPromise;
}

// anotherfile.js
var db = require('./db');
db.getDb().then(function (db) {
  // This callback will never run until the connect promise has
  // resolved and the db is ready.  Calling `getDb` again will not
  // initiate another call to `MongoClient.connect`
  console.log(db);
});