Nodejs的异步调用循环

nodejs loop of async calls

本文关键字:循环 调用 异步 Nodejs      更新时间:2023-09-26

在这个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个时隙"。我怀疑create函数是异步的,当它完成的时候,我们已经不在那里更新计数器了。那么我如何计算这些记录呢?(我知道我可以使用循环的计数器,但我计划做验证在某些情况下,不创造记录。谢谢:)

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');
  });
}

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

计数器在每次调用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');
}

将计数器移到传递给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');

}