javascript - for 循环内的 async.waterfall 逃脱了 for 循环

标签 javascript node.js mongodb asynchronous mongoose

POST 类型的 Form Action 上,我们获取 Node.JS/Express 中的所有值并尝试将其保存到 >MongoDB.

隐藏字段确定来自前端 javascript 的属性的长度,并且它的值更新为隐藏字段的值。

此长度在后端( Node )中用于迭代项目列表。

我有一个 async.waterfall 函数和一个像这样在其中运行的 for 循环

async.waterfall([
function(callback){
       var itemLength = req.body.itemLength;
        var itemProp,itemComponent;
        var destination;
        var destinationsArray =[];

        for(var k=1; k<=itemLength; k++){

            destination = new Destination({
                name: req.body['destinationName'+k],
            });

            itemComponent = {
              "itemCompProp" : req.body['itemCompProp'+k]
            };


            itemProp = new ItemProp({
               itemComponent: itemComponent
            });

            itemProp.save(function(err,itemPropSaved){
              destination.newProperty = itemPropSaved._id

              destination.save(function(err,destinationSaved){
                if(err){
                  console.log("Error== " + err);
                }
                else{
                  destinationsArray.push(destinationSaved._id);
                }
              });

            });
         }// End of For
  callback(null,destinationsArray);
},
function(destinationsArray,callback){
   var brand = new Brand({
    name : req.body.brandName,
  });

  brand.save(function(err,brandSaved){
      if(err){
          console.log("Error== " + err);
        }else{
            console.log('Brand Saved');
        }
   });
   callback(null);
}
], function (err, status) {
  if(err){
    req.flash('error', {
          msg: 'Error Saving Brands'
      });

     console.log("Error : " + err); 
  }  
  else{
      console.log("Brand Saved."); 
      req.flash('success', {
          msg: 'Brand Successfully Added!'
      });
  }
});

res.redirect('/redirectSomewhere');

当我们运行它时,destinationsArray 首先作为 null 返回,而不是通过 for 循环 然后返回正确的destinationsArray 的值超过目的地的长度 (itemLength)。

我们希望进程是同步的。我们还尝试使用闭包包装 for Loop 但无济于事。

我们不能使用 async.eachSeries 而不是 for Loop 因为我只是迭代一个数字属性而我们没有任何 要迭代的文档

async.waterfall 中运行 for Loop 的任何可行解决方案?

提前干杯和感谢。

最佳答案

您那里的代码几乎没有问题:

  1. 调用回调的地方。
  2. 调用 res.redirect() 的地方。
  3. for 循环。

save() 是异步的。常规的 for 循环将直接继续,而无需等待所有 save() 调用完成。这就是 destinationsArray 为空的原因。正如您所说,您不能使用 async.eachSeries() 因为您正在遍历数字属性。但是,您在正确的轨道上。 Async.whilst() 就是这样做的。以下是使用 Async.whilst() 和回调的正确调用位置修改后的代码:

async.waterfall([
  function(callback){
    var itemLength = req.body.itemLength;
    var itemProp,itemComponent;
    var destination;
    var destinationsArray =[];
    var k = 1;  // 1st part of for loop:  for(k=1; k<=itemLength; k++)

    async.whilst(
      function() {
        return k <= itemLength;  // 2nd part of for loop:  for(k=1; k<=itemLength; k++)
      },
      function(whilstCb) {
        destination = new Destination({
          name: req.body['destinationName'+k]
        });

        itemComponent = {
          "itemCompProp" : req.body['itemCompProp'+k]
        };

        itemProp = new ItemProp({
          itemComponent: itemComponent
        });

        itemProp.save(function(err,itemPropSaved){
          destination.newProperty = itemPropSaved._id

          destination.save(function(err,destinationSaved){
            if(err){
              console.log("Error== " + err);
            } else {
              destinationsArray.push(destinationSaved._id);
            }
            k++;  // 3rd part of for loop:  for(k=1; k<=itemLength; k++)
            whilstCb(null);
          });
        });
      },
      function(err) {
        // It gets here once the loop is done
        console.log(destinationsArray);  // This array should have all the values pushed
        callback(null, destinationsArray);
      }
    );
  },
  function(destinationsArray,callback){
    var brand = new Brand({
      name : req.body.brandName
    });

    brand.save(function(err,brandSaved){
      if(err){
        console.log("Error== " + err);
      } else {
        console.log('Brand Saved');
      }
      callback(null);
    });
  }
], function (err, status) {
  if(err){
    req.flash('error', {
      msg: 'Error Saving Brands'
    });
    console.log("Error : " + err);
  } else {
    console.log("Brand Saved.");
    req.flash('success', {
      msg: 'Brand Successfully Added!'
    });
  }
  res.redirect('/redirectSomewhere'); 
});

关于javascript - for 循环内的 async.waterfall 逃脱了 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29841854/

相关文章:

javascript - 我的服务没有更新 - Angularjs

Javascript 解析特定字符串的不同部分

java - 嵌套数组内的Mongodb增量值

javascript - 按另一个数组对对象数组进行排序

node.js - done 不是 passport js 中的函数错误

mysql - 使用唯一索引与查询数据库

node.js - 如何在nodejs中集成unicommerce的soap xml API

node.js - Mongodb根据属性将结果拆分为数组

javascript - 如何在 mongodb 中维护排序的属性顺序?

javascript - 我们可以在对象构造函数中分配一个公共(public)方法吗? (javascript)