Mongoose承诺通过问题的论点

时间:2014-11-23 23:01:41

标签: mongoose promise

我尝试使用链式promise构造来为我的mongodb数据库播种。

非工作代码

var p = new mongoose.Promise();
p
  .then(function() {
    //remove all categories
    return Category.remove({}).exec();
  })
  .then(function() {
    //remove all competitors
    return Competitor.remove({}).exec();
  })
  .then(function() {
    //add categories
    return Category.create({
      name: 'cat1',
      info: 'Category #1'
    }, {
      name: 'cat2',
      info: 'Category #2'
    });
  })
  .then(function(cat1, cat2) {
    //add competitors
    return Competitor.create([{
      first_name: 'Titi',
      last_name: 'Tito',
      _category: cat1._id
    }, {
      first_name: 'Tata',
      last_name: 'Tato',
      _category: cat2._id
    }]);
  })
  .then(function() {
    console.log('finished populating models');
  })
  .end(function(err) {
    console.log(err);
  });

我收到一条错误,说cat2未定义。

工作代码

如果我这样做,它有效,但我不明白为什么

var p = new mongoose.Promise();
p
  .then(function() {
    //remove all categories
    return Category.remove({}).exec();
  })
  .then(function() {
    //remove all competitors
    return Competitor.remove({}).exec();
  })
  .then(function() {
    //add categories
    return Category.create({
      name: 'cat1',
      info: 'Category #1'
    }, {
      name: 'cat2',
      info: 'Category #2'
    })
    .then(function(cat1, cat2) {
      //add competitors
      return Competitor.create([{
        first_name: 'Titi',
        last_name: 'Tito',
        _category: cat1._id
      }, {
        first_name: 'Tata',
        last_name: 'Tato',
        _category: cat2._id
      }]);
    });
  })
  .then(function() {
    console.log('finished populating models');
  })
  .end(function(err) {
    console.log(err);
  });
p.fulfill();

有人知道第一个代码的内容是什么吗?

1 个答案:

答案 0 :(得分:0)

只能Category.create返回一种奇怪的承诺,其.then()接受一个接收两个(或更多)参数的成功函数 - 非常像jQuery .then()

在非工作版本中,.then()被间接链接,以便外部mongoose promise链被赋予奇数 - 使用其两个参数解析的promise。并且mongoose的.then()在处理这种情况方面只是部分成功 - 回调是通过一个参数传递而不是两个,所以在到达行_category: cat2._id时会抛出错误。

在工作版本中,这不是问题,因为.then()直接链接,形成一个内部奇数链,第二部分拾取第一部分的参数。在这种情况下,外部猫鼬承诺链继续没有错误,因为虽然它(很可能)也用两个参数解决了奇数 - 但它不会尝试对它们中的任何一个进行操作。

如果我的分析是正确的,那么你应该能够通过“解扩”奇数承诺的多个参数来使非工作模式工作,如下所示:

function unspread() {
    return Array.prototype.slice.apply(arguments);
}

var p = new mongoose.Promise();

p.then(function() {
    return Category.remove({}).exec();//remove all categories
}).then(function() {
    return Competitor.remove({}).exec();//remove all competitors
}).then(function() {
    //add categories
    return Category.create({
        name: 'cat1',
        info: 'Category #1'
    }, {
        name: 'cat2',
        info: 'Category #2'
    }).then(unspread);
}).then(function(arrayOfParams) {
    //add competitors
    return Competitor.create([{
        first_name: 'Titi',
        last_name: 'Tito',
        _category: arrayOfParams[0]._id
    }, {
        first_name: 'Tata',
        last_name: 'Tato',
        _category: arrayOfParams[1]._id
    }]);
}).then(function() {
    console.log('finished populating models');
}).end(function(err) {
    console.log(err);
});

p.fulfill();

我并不是说这是一个比你的工作版本更好的解决方案,但也许(如果它有效)这是一个技巧,你可以在另一个场合保持袖手旁空。