在 post 请求中使用 mongodb 插入多个文档

Inserting multiple documents with mongodb in a post request

在同一个请求中使用 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
        });
    });

承诺 return 立即 但它们的 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
    });  
    */
  });
});