Express js,mongodb:" ReferenceError:db未定义"当在post函数之外提到db时

时间:2016-01-02 12:48:19

标签: node.js mongodb express

index.js文件:

var express = require('express');
var router = express.Router();

function validCheck (exp,name) {
    return exp.test(name);
}
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index');
});

var user=db.collection('user'); //gives reference error,db is not defined

router.post('/',function(req,res,next){
    username=req.body.username;
    password=req.body.password;
    //var user=db.collection('user'); //works fine
    user.findOne({'username':username,'password':password},function(err,docs){
        //do something
    });
});

module.exports = router;

var user=db.collection('user')之外使用router.post时,它会给出错误,但在router.post内使用相同内容时,它会正常工作。

这里可能缺少什么概念?

编辑:涉及mongodb

的App.js文件的一部分
var mongodb= require('mongodb');
var MongoClient= mongodb.MongoClient;
var URL = 'mongodb://127.0.0.1:27017/mainDB';

MongoClient.connect(URL,function(err,database){
  if(!err){
    db=database;
  }
  else{
    //do something
  }
});

3 个答案:

答案 0 :(得分:1)

记住MongoClient.connect()是异步的。执行var user=db.collection('user');时,数据库连接可能尚未就绪。数据库连接已成为回调完成的一个,不早于此。

第一个请求完成后,恰好就建立了数据库连接。你等待的时间越长,它就越有效,但这仍然是错误的做法。

使用全局变量也是不好的做法,导致混淆和the UIElementCollection source code

简而言之,代码应该看起来像

// module database.js
var mongodb= require('mongodb');
var MongoClient= mongodb.MongoClient;
var URL = 'mongodb://127.0.0.1:27017/mainDB';

var db;
var error;
var waiting = []; // Callbacks waiting for the connection to be made

MongoClient.connect(URL,function(err,database){
  error = err;
  db = database;

  waiting.forEach(function(callback) {
    callback(err, database);
  });
});

module.exports = function(callback) {
  if (db || error) {
    callback(error, db);
  } else {
    waiting.push(callback);
  }
}
}

比使用它

var db = require('database.js');

router.post('/',function(req,res,next){
  username=req.body.username;
  password=req.body.password;

  db.conn(function(err, database) {
    if (err) {
      res.sendStatus(500);
      console.log(err);
      return;
    }

    database.collection('users').findOne({'username':username, 'password':password}, function(err, docs){
      //do something
    });
  });
});

请注意,连接是在第一个require上进行的,因此如果您在App.js中添加require('database.js');。你没有在第一次请求时失去它。

或者你可以使用other problems来处理等待逻辑。

答案 1 :(得分:0)

您缺少的是执行时间。

当node.js处理var user时,router.post外的index.js行会立即执行。

var user内的router.post行仅在客户请求您的应用的/页面时执行。

db变量仅在成功连接到MongoDB后分配。对于第一个var user行来说,这已经太迟了,但是第一个HTTP请求到了/的时候已经太晚了。

答案 2 :(得分:0)

MongoClient.connect的回调函数只有在连接到数据库后才会异步调用。当时只有db定义为全局变量。

假设您需要app.js中的index.js文件。 var user=db.collection('user');外的router.post行同步执行。到执行此行时,db将无法定义。

var user=db.collection('user');内的行router.post是异步执行的。因此,当执行该代码时,已经定义了db。

问题:

  

我在这里缺少什么概念?

我建议您了解异步javascript执行https://stackoverflow.com/a/7104633/3492210