【问题标题】:nodejs loop of async calls异步调用的nodejs循环
【发布时间】:2016-06-29 01:49:31
【问题描述】:

在这个 nodejs 函数中,我在 mongodb 中创建了几条记录 使用猫鼬。计数器计算多少。

export function createTimeslots(req, res){
  var startDate = req.body.startDate;
  var Duration = req.body.Duration;
  var repeat = req.body.repeat;
  var counter=0;

  for(var i=0; i<repeat; i++){
    var startTime = ... calculation
    var endTime = ...calculation

    var ts = {
      startTime: startTime,
      endTime: endTime,
    };

    TimeSlot.create(ts, function(err, timeslot){
        counter = counter+1;
    });
  }

  res.status(200).json(counter + ' timeslots created');

}

问题在于结果始终是“创建了 0 个时隙”。 我怀疑创建函数是异步的,当它完成时, 我们不再在那里更新计数器。 那么我该如何计算这些记录呢? (我知道我可以使用循环的计数器,但我计划进行验证 在某些情况下不创建记录。谢谢:)

【问题讨论】:

    标签: javascript node.js mongoose


    【解决方案1】:

    Promises 会在这里为您提供帮助:

    export function createTimeslots(req, res){
      var startDate = req.body.startDate;
      var Duration = req.body.Duration;
      var repeat = req.body.repeat;
      var counter=0;
    
      var promises = [];
    
      for(var i=0; i<repeat; i++){
        var startTime = ... calculation
        var endTime = ...calculation
    
        var ts = {
          startTime: startTime,
          endTime: endTime,
        };
    
        promises.push(new Promise(function(resolve) {
          TimeSlot.create(ts, function(err, timeslot) {
            counter = counter+1;
            resolve();
          });
        }));
      }
    
      Promise.all(promises).then(function() {
          res.status(200).json(counter + ' timeslots created');
      });
    }
    

    这将等到所有异步操作都完成,然后才继续并创建返回消息。

    【讨论】:

    • 你可能也应该做一些事情来拒绝错误的承诺
    • 太棒了。谢谢!
    【解决方案2】:

    每次调用 createTimeslots 时,计数器都会设置为 0,因此将其设为模型变量

    var counter=0;
    export function createTimeslots(req, res){
      var startDate = req.body.startDate;
      var Duration = req.body.Duration;
      var repeat = req.body.repeat;
     
      for(var i=0; i<repeat; i++){
        var startTime = ... calculation
        var endTime = ...calculation
    
        var ts = {
          startTime: startTime,
          endTime: endTime,
        };
    
        TimeSlot.create(ts, function(err, timeslot){
            counter = counter+1;
        });
      }
      
      res.status(200).json(counter + ' timeslots created');
    
    }

    【讨论】:

    • counter 在异步函数中递增,在调用 res.status 行时可能尚未执行。充其量这是一个竞争条件,在最坏的情况下,这是行不通的。
    • 如果回调异步运行,这将无法解决问题。
    • case 计数器在异步函数中递增,像 TimoSta 一样使用 promise @mkoryak
    • 它是异步的。问题说mongodb
    • @mkoryak 你的意思是在这个请求中,我认为你完全想要,目前还不清楚
    【解决方案3】:

    将计数器移到您传递给 TimeSlot 创建方法的异步回调主体之外。

    export function createTimeslots(req, res){
      var startDate = req.body.startDate;
      var Duration = req.body.Duration;
      var repeat = req.body.repeat;
      var counter=0;
    
    
      for(var i=0; i<repeat; i++){
        var startTime = ... calculation
        var endTime = ...calculation
    
        var ts = {
          startTime: startTime,
          endTime: endTime,
        };
    
        counter = counter+1;
    
        TimeSlot.create(ts, function(err, timeslot){
            // do stuff with counter
    
        });
      }
    
      res.status(200).json(counter + ' timeslots created');
    

    }

    【讨论】:

    • 除非创建失败,这是谎言
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 2019-02-15
    • 1970-01-01
    相关资源
    最近更新 更多