我正在尝试获取数据库中的项目数,以确认数据插入是否成功。
注意:我知道这可以使用一些简单的函数来实现:
dbName.equal(insertSize, result.insertedCount)
但是,我是javascript的新手,我认为我已经遇到了实现异步回调的需求,所以我想弄清楚这一点。
插入功能
var insertMany = function() {
// get initial count
var count1 = getDbCount();
// Insert new 'data'
MongoClient.connect(url, function(err, db) {
var col = db.collection(collectionName);
col.insert(data, {w:1}, function(err,result) {});
db.close();
});
/** This needs to be implemented through next/callback
after the insert operation **/
var count2 = getDbCount();
/** These final console logs should be executed after all
other operations are completed **/
console.log('[Count] Start: ' + count1 + ' | End:' +count2);
console.log('[Insert] Expected: ' + data.length + ' | Actual: ' + (count2 - count1));
};
获取数据库计数功能
var getDbCount = function() {
MongoClient.connect(url, function(err, db) {
if (err) console.log(err);
var col = db.collection(collectionName);
col.count({}, function(err, count) {
if (err) console.log(err);
db.close();
console.log('docs count: ' + count);
// This log works fine
});
});
return count; // this is returning as undefined since this is
// executing before the count operation is completed
};
我收到错误,因为在所需的操作完成之前发生了返回。
感谢您的帮助。
[编辑]带有承诺的getCount函数
我已将承诺添加到getCount函数作为开头:
var getCount = function() {
var dbCount = 0;
var promise = new Promise(function(resolve, reject) {
MongoClient.connect(url, function(err, db) {
if (err) {
console.log('Unable to connect to server', err);
} else {
console.log('Database connection established:' + dbName);
}
// Get the collection
var col = db.collection(collectionName);
col.count({}, function(err, count) {
if (err) console.log(err);
db.close();
console.log('docs count: ' + count);
resolve(null);
dbCount = count;
});
});
});
promise.then(function() {
return dbCount;
});
};
console.log(getCount());
输出仍然是: 未定义 建立数据库连接:testdb docs:500
然后({return count})代码仍然在promise {db.count()}之前执行。它在数据库操作完成之前返回undefined。
答案 0 :(得分:2)
通常,您遇到的问题是,当函数返回时,您希望值已存在。对于异步功能,通常情况并非如此。有关异步处理的大量信息(不要像在Java中那样与并行处理混淆)。
我创建了一个适合您情况的示例:
https://jsfiddle.net/rh3gx76x/1/
var dummyCount = 5
getCount = function() {
return new Promise(function(resolve, reject) {
setTimeout(function() { // this would be your db call, counting your documents
resolve(dummyCount); // dummy for number of documents found
}, 100 * Math.random());
});
};
insertMany = function() {
return new Promise(function(resolve, reject) {
setTimeout(function() { // this would be your db call, writing your documents
dummyCount += 2;
resolve();
}, 100 * Math.random());
});
};
runIt = function(callback) {
var count1;
getCount().then(function(count) {
console.log("First callback with value ", count);
count1 = count;
insertMany().then(function() {
getCount().then(function(count2){
console.log("Second callback with value ", count2);
callback(null, count1, count2);
});
})
})
}
runIt(function(err, count1, count2) {
console.log("count1: " + count1 + ", count2: " + count2);
});
最后一件事。您可能想要查看“异步”包。这对于提供大量辅助函数和控制流程的问题有很大帮助。
答案 1 :(得分:0)
在操作完成之前返回的原因是nodejs的asynchronous
设计,继承自javascript。当程序向前移动并遇到Mongoose.connect()
时,return
的回调将被执行操作。
您还没有提供使您在错误声明中找到的解决方法,因此我无法评论您在那里做了什么错误。但是,考虑到您第一次完成开始的工作,确保Mongoose.connect()
完成然后执行return语句的最佳方法是使用JavaScript的promise。使用promises将使Mongoose.connect()
执行,然后将控件传递给return语句。
您的代码将类似于:
插入功能:
var insertMany = function() {
// get initial count
var count1 = getDbCount();
// Insert new 'data'
var promise = new Promise(
function(resolve,reject){
MongoClient.connect(url, function(err, db) {
var col = db.collection(collectionName);
col.insert(data, {w:1}, function(err,result) {});
db.close();
resolve(null);
});
}
);
promise.then(function(val){
var count2 = getDbCount();
/** These final console logs should be executed after all
other operations are completed **/
console.log('[Count] Start: ' + count1 + ' | End:' +count2);
console.log('[Insert] Expected: ' + data.length + ' | Actual: ' + (count2 - count1));
});
同样,您可以向GetDB
函数添加承诺。
执行承诺时的关键点是:
then()
包含执行promise后要同步执行的函数部分。它由resolve
调用,传递的参数在catch
函数的回调中接收。catch()
包含在promise中遇到错误时调用的函数部分。它由reject
调用,传递的参数在catch
函数的回调中接收。编辑:承诺的另一种选择是async.js,只是它与外部模块不同,与承诺不同。