在post请求中插入带有mongodb的多个文档

时间:2016-04-01 17:59:53

标签: javascript node.js mongodb express es6-promise

在同一个请求中使用mongodb插入多个文档我得到了未定义的值。

.post(function (req, res) {
    ...
    Item.create(data)
    .then(function (item) {

        var modelOtherItem;            

        OtherItem.create({
            ...
        }).then(function (otherItem){
            modelOtherItem = otherItem; 
            modelOtherItem; // here I get the expected value       
        });

        res.status(201);

        res.json({
            item: item, // has a value
            otherItem: modelOtherItem // -> is undefined
        });
    });

1 个答案:

答案 0 :(得分:4)

承诺立即返回,但他们的then回调是异步执行的。这意味着您在分配值之前访问modelOtherItem 。最简单的解决方法是在then回调中添加代码(您也可以删除modelOtherItem变量):

post(function (req, res) {
  // ...
  Item.create(data)
  .then(function (item) {

    OtherItem.create({
        // ...
    }).then(function (otherItem){            

        // add code here
        res.status(201);

        res.json({
          item: item, // has a value
          otherItem: otherItem // also has value
        });     
    }); 
});

有一点需要注意,您可以通过将数组传递到Model.collection.insert(array...来创建所有项目,或者,如果使用Mongoose,则Model.create(array...

替代解决方案

如果您可以彼此独立地创建模型(意味着任何项目的创建不依赖于任何其他项目),您可以使用Promise.all方法来获取一系列承诺并一次性解析该数组中的承诺也解决了:

post(function (req, res) {
  // ...

  // create an array that will hold item creation promises
  let promises = [];

  // add the promise that creates the item
  promises.push(Item.create(...));

  // add the promise that creates the other item
  promises.push(OtherItem.create(...));

  Promise.all(promises)
  .then(function(results) { // this function is called once all promises in the array `promises` resolve
    // results contains the resolved data from each promises in the array
    // in the order of the promises

    var item = results[0];
    var otherItem = results[1];

    // OR you can use ES6 `let` declaration with 
    // destructuring to achieve the same as above
    // in a cleaner way:
    // let [item, otherItem] = results;

    res.status(201);

    res.json({
      item: item,
      otherItem: otherItem
    });  

    // in ES6, if both the object property name and the variable name are the same
    // you can just specify the name once and achieve the same effect as above
    // with less code:
    /*
    res.json({
      item,
      otherItem
    });  
    */
  });
});