简体   繁体   中英

nodejs while loop not working as expected - becomes infinite

I've created a middleware to delete aws files when I create a new profile picture / cover photo upload.

//if previous awsKeys detected in req.body / images are detected : delete them.
exports.multipleDelete = function(req, res, next){
  var body = req.body;
  var awsKeyTrash = body.existingKeys;
  if(awsKeyTrash !== undefined){
    var j = 0;
    while (j < awsKeyTrash.length){
      console.log('j ', j)
      var key = awsKeyTrash[j];
      s3.deleteObject({
        Bucket: aws.bucket,
        Key: key
      }, function(err,data){
        if (err){
           console.log('delete err', err);
            j++;
          };
        console.log('deleted')
        res.send('deleted');
        j++;
      });
    }
    next();
  }
  else{
    next();
  }
}

console.log results:

j  0
j  0
j  0
j  0
j  0
j  0
j  0
j  0
j  0
j  0 .....

With the code above, I get an infinite loop. However, it works fine if I use a for loop instead..

s3.deleteObject is an asynchronous call, you immediately iterate your while loop while the call is still being made!

You should consider using an asynchronous framework like async . Code would look like this:

//if previous awsKeys detected in req.body / images are detected : delete them.
exports.multipleDelete = function(req, res, next){
  var body = req.body;
  var awsKeyTrash = body.existingKeys;
  if(awsKeyTrash !== undefined){
    var j = 0;
    async.whilst(
      function(){ return j < awsKeyTrash.length; }
      function(){
        console.log('j ', j)
        var key = awsKeyTrash[j];
        s3.deleteObject({
          Bucket: aws.bucket,
          Key: key
        }, function(err,data){
          if (err){
             console.log('delete err', err);
              j++;
          };
          console.log('deleted')
          res.send('deleted');
          j++;
        });
      },
      function(err){
        //while loop is finished!
        next();
    });
  }
  else{
    next();
  }
}

There is problem in your WHILE conception - s3.deleteObject waits for a callback so it's asynchronous function. Such a function doesn't block your program's flow, so the next part of the code could be still working.

So your while loop doesn't waits for deleteObject results. The next turn of loop is performed while object isn't deleted yet.

//if previous awsKeys detected in req.body / images are detected : delete them.
exports.multipleDelete = function(req, res, next){
  var body = req.body;
  var awsKeyTrash = body.existingKeys;
  if(awsKeyTrash !== undefined){
    var j = 0;
    while (j < awsKeyTrash.length){
      console.log('j ', j)
      var key = awsKeyTrash[j];
      s3.deleteObject({
        Bucket: aws.bucket,
        Key: key
      }, /*function(err,data){
        if (err){
           console.log('delete err', err);
            j++;
          };
        console.log('deleted')
        res.send('deleted');
        j++;
      }*/);
    }
    next();
  }
  else{
    next();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM