同步函数调用nodejs mongodb驱动程序

我有一个处理mongodb数据库的开源项目。 我试图做一个函数,查询数据库来检查是否存在条目。

问题是,当if_exists()返回true或false时,由于mongodb驱动函数是asynchronous的,所以返回undefined。 该文件是Query.js ,我已经尝试了解决scheme在这里解决这个问题什么是正确的方法,使Node.js中的同步MongoDB查询? 但仍然得到一个未定义的结果与get方法。

做这个工作的最好方法是什么?

unit testing的输出如下:

 running unit tests... add query test exists tests: get: undefined {} should be true: undefined get: undefined {} should be false:undefined Captains Logs listening on port 3000 Captains_Logs v0.5.0-21 [ { name: 'rhcp', _id: 50cbdcbe9c3cf97203000002 } ] [ { name: 'os', _id: 50cbdcbe9c3cf97203000001 } ] 

您可以在WeaponXI / cplog上浏览整个代码

或者快速查看一下query.js代码是:

 var DB = require('../../lib/db.js').DB; function methods() { //query object var Q = {}; //will act as our private variables to workaround asynchronous functions. //will delete non-required ones when done -- we don't have to, but just for continuity. exports.privates = {}; //add tag to collection Q.add = function(tag) { if (typeof tag === "string") { //maybe we are adding a tag by name var obj = { name: tag }; } else if (typeof tag === "object" && tag.name) { //maybe the tag object was specified, and tag's name was provided var obj = tag; } require('mongodb').connect(DB.mongo_url, function(err, db) { db.collection('tags', function(err, coll) { coll.insert(obj, { safe: true }, function(err, result) { console.log(result); }); }); }); } var callback = { _set: function(key, val) { exports.privates[key] = val; //console.log(JSON.stringify(privates)); }, _get: function(key) { console.log("get: "+exports.privates.key); console.log(JSON.stringify(exports.privates)); return exports.privates[key]; }, _unset: function(key) { delete privates[key]; } } var if_exists = function(query, where, callback) { require('mongodb').connect(DB.mongo_url, function(err, db) { db.collection(where, function(err, coll) { coll.findOne(query, function(e, r) { //console.log(r); if (r === null) { callback._set("does_exist", false); } else { callback._set("does_exist", true); } }); }); }); var result = callback._get("does_exist"); // delete privates.does_exist; return result; } Q.if_exists = function(query, where) { if_exists(query, where, callback); } return Q; } var query = exports.query = methods(); function unit_test_add() { console.log("add query test"); query.add("os"); query.add({ name: "rhcp" }); } function unit_test_if_exists() { console.log("exists tests:"); console.log("should be true: " + query.if_exists({ name: "os" }, "tags")); console.log("should be false:" + query.if_exists({ name: "ossuruk" }, "tags")); } function unit_tests() { console.log("running unit tests..."); unit_test_add(); unit_test_if_exists(); } unit_tests(); 

解:

Query.js Query.test.js Gists

感谢JohnnyHK!

不能使用asynchronous结果作为函数的返回值。 就这么简单。 您必须通过作为函数参数提供的callback(或使用futures / promises并有效推迟该步骤,但涉及更多)来将asynchronous结果传递给调用方。

if_exists应该看起来像这样:

 var if_exists = function(query, where, callback) { require('mongodb').connect(DB.mongo_url, function(err, db) { db.collection(where, function(err, coll) { coll.findOne(query, function(e, r) { //console.log(r); if (r === null) { callback(e, false); } else { callback(e, true); } // You should either close db here or connect during start up // and leave it open. db.close(); }); }); }); }