可以在node.js模块中asynchronous初始化导出吗?

由于MongoDB数据库访问和初始化在Node.js上是asynchronous的,所以我想为每个集合定义一个模块,在db初始化之后导出包装数据库调用。

这样的“Cars.model.js”模块看起来像这样:

var db = require("mongodb"); db.collection("cars", function(err, col) { exports.getCars = function(callback) { col.find({}, callback); }; }); 

以便其他模块可以运行:

 var carModel = require("Cars.model.js").getCars; getCars(err, cars) { // (do something with cars here...) }; 

它发生在我身上, getCars是未定义的,因为数据库访问尚未初始化时,我的第二个模块运行。

你如何处理创build这样的asynchronous数据库模型?

离开文件后,您不能写入exports 。 你必须阻止。 为了避免被阻塞,我会使用延迟加载的资源。

 var carCol; var carEmitter = new require("events").EventEmitter; exports.getCars = function(callback) { // if no car collection then bind to event if (carCol === undefined) { carEmitter.on("cars-ready", function() { callback(carCol); }); } else { // we have cars, send them back callback(carCol); } } db.collection("cars", function(err, col) { // store cars carCol = col; // tell waiters that we have cars. carEmitter.emit("cars-ready"); }); 

使用事件发射器来模拟延迟加载。 你可能想推广到一个LazyLoadedCollection类/对象,使代码更干/更干。

我是新来的所以不要生我的气

我正在使用承诺这样做:

 var db = require("mongodb"), Q = require('q'), getCarsDefer = Q.defer(); exports.getCars = getCarsDefer.promise; db.collection("cars", function(err, col) { if(err){ getCarsDefer.reject(err); }else{ getCarsDefer.resolve(Q.ninvoke(col,'find')); }; }); 

所以你可以这样得到你的车:

 var carModel = require("Cars.model.js").getCars; getCars.then(cars) { // (do something with cars here...) }; 

这是一个坏主意,请让我知道,因为这正是我现在正在做的事情。

我相信这个简单的解决scheme的工作原理:通过同步调用集合cachingreplaceasynchronous调用getCars() ,将调用模型之前将填充集合caching。

main.js应用程序启动器模块:

 var db = require("mongodb"); exports.collectionCache = {}; db.collection("cars", function(err, col) { exports.collectionCache["cars"] = col; // ready => start application logic (incl. models) here }); 

因此“Cars.model.js”看起来像这样:

 var col = require("main").collectionCache; // populated exports.getCars = function(callback) { col["cars"].find({}, callback); }; 

该解决scheme将asynchronous问题从模型移动到根数据库模型,使模型更容易开发。