奇怪的Mongoose行为 - 文件不会保存到DB中

时间:2014-05-23 04:46:57

标签: node.js mongoose async.js

在下面的代码中,我尝试使用一些测试数据填充我的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(已保存)会成功地将每个新文档打印到控制台。 - 如果我删除了第一个异步功能(删除所有记录) - 那么新文档将保存到数据库中。

一个猫鼬的怪癖或我对异步流的误解..?

3 个答案:

答案 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