6

我想在 app.js 文件中通过 Node-Mongo-Native-Driver 打开并初始化数据库,然后将其保持打开状态并读取路由。我将以下代码放入 app.js 并包装 app.gets 以便在打开数据库时使它们可用:

var mongoClient = new MongoClient(new Server('localhost', 27017));
mongoClient.open(function(err, mongoClient) {
  var db1 = mongoClient.db("dev-db")
    , products = db1.collection('products');
  app.get('/', routes.index);
  app.get('/users', user.list);
});

当我现在尝试读取 index.js 路线中的数据库时,我得到了

ReferenceError: products is not defined

我认为 index.js 应该能够访问产品,因为它是在外部函数中定义的,因为在初始化中包装了 app.gets。

除了第二个问题: MongoClient.open 和 MongoClient.connect 有什么区别

4

1 回答 1

5

JavaScript 使用词法作用域——意思是,如果你这样做,它会起作用:

var mongoClient = new MongoClient(new Server('localhost', 27017));
mongoClient.open(function(err, mongoClient) {
  var db1 = mongoClient.db("dev-db")
    , products = db1.collection('products');
  app.get('/', function closedOverIndexRoute(req, res, next) {
    console.log(products); // this will work
  });
  app.get('/users', user.list); // however, user.list will not be able to see `products`
});

一个函数不会成为一个闭包(不保留其封闭函数的值),除非它是在闭包内部的词法(写入)。

但是,您可能不想将整个应用程序编写为一个大闭包。相反,您可以使用 export 和 require 来访问您的产品集合。例如,在一个名为 mongoconnect.js 的文件中:

var mongoClient = new MongoClient(new Server('localhost', 27017));
var products;

mongoClient.open(function(err, mongoClient) {
  var db1 = mongoClient.db("dev-db");
  products = db1.collection('products');
});

module.exports = {
  getProducts: function() { return products; }
};

然后在你的 index.js 文件中:

var products = require('mongoconnect').getProducts();

另一种选择(如果您只想保留 app 和 index)是使用一对闭包:

index.js:

module.exports = function(products) {
  return function index(req, res, next) {
    console.log(products); // will have closed-over scope now
  };
};

app.js,在里面,定义mongoClient.open()在哪里:products

var index = require('./index')(products);
于 2013-01-29T05:03:25.240 回答