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

Inserting multiple documents with mongodb in a post request

本文关键字:插入 文档 mongodb post 请求      更新时间:2023-11-13

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

Promises立即返回,但它们的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方法,该方法接受一个Promise数组,并在该数组中的所有Promise也解析后解析:

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
    });  
    */
  });
});