在下面的代码中,我尝试使用一些测试数据填充我的dev DB。我想首先删除所有文档,然后添加新的测试文档:
var mongoose = require('mongoose')
, Plan = mongoose.model('Plan')
, Async = require('async')
Async.series([
function(callback){
// delete all records
Plan.find(function(err,docs){
for (d in docs)
Plan.remove(d, function(err) {
if (err) console.log("error removing records " + err)
});
});
callback();
},
function(callback){
var planArray = [
{title: 'Plan A', body: 'Restaurant Financial Plan'},
{title: 'Plan B', body: 'Coffeeshop Financial Plan'},
{title: 'Plan C', body: 'bar Financial Plan'}
]
var arrayLength = planArray.length;
for (var i = 0; i < arrayLength; i++) {
var p = new Plan(planArray[i])
p.save(function(err, saved){
if (err)
{console.log("error creating fixture " + err)}
else {
console.log(saved)
}
})
}
callback();
}
])
有趣(奇怪)的行为是这样的: - 代码运行并删除所有文档但不添加新的测试文档。 - 控制台上没有错误,console.log(已保存)会成功地将每个新文档打印到控制台。 - 如果我删除了第一个异步功能(删除所有记录) - 那么新文档将保存到数据库中。
一个猫鼬的怪癖或我对异步流的误解..?答案 0 :(得分:2)
有一些问题。首先,你有一个for
循环触发异步删除,但这些循环可能在你第一次回调被调用之前没有完成。最好改为使用Async.each
。
此外似乎还发生了一些函数命名冲突。因此,有关此的完整示例,请参阅以下内容:
var mongoose = require('mongoose'),
Async = require('async'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var planSchema = new Schema({
title: String,
body: String
});
var Plan = mongoose.model('Plan',planSchema);
Async.series([
function(call1) {
Plan.find(function(err,docs) {
if (err)
throw err;
if ( docs.length > 0 ) {
Async.each( docs, function(d, call2) {
Plan.remove(d, function(err) {
if (err)
throw err;
console.log( "deleting: " + d );
call2();
});
});
}
});
call1();
},
function(call3) {
var planArray = [
{ title: 'Plan A', body: 'Plan A' },
{ title: 'Plan B', body: 'Plan B' }
];
var arrayLength = planArray.length;
for ( var i = 0; i < arrayLength; i++ ) {
var p = new Plan(planArray[i]);
p.save(function(err,saved) {
if (err)
throw err;
console.log( "saving: " + saved );
});
}
call3();
}
]);
答案 1 :(得分:1)
我的猜测是后者 - 对异步流的误解。在查找和删除文档之前,将调用第一个函数的回调。因此,当您仍在查找并删除它们时,您已经在第二个函数中添加了更多内容 - 但这些函数将在第一个函数中找到并删除。
只有在删除所有文档后才需要调用第一个回调。尝试在async.each
回调中添加Plan.find
:
Async.series([
function(callback){
// delete all records
Plan.find(function(err, docs){
Async.each(
docs, // your array
function removeDoc(d, cb) { // iterator function
Plan.remove(d, function (err) {
if (err) console.log("error removing records " + err);
return cb();
});
},
callback // executed after the iterator is done
);
},
...
顺便说一下,我相信Plan.remove({}, function(err){...})
会删除所有文档 - 除非您正在做其他事情,否则无需迭代每个文档。
答案 2 :(得分:0)
第二个函数在你调用callback()之后开始执行,i。即在查找和删除呼叫之前。你必须等到查找和删除完成并调用callback()。 看一下异步的队列方法:https://github.com/caolan/async#queue