简体   繁体   English

承诺循环内等待

[英]Promises inside loop to wait

I have this code: 我有以下代码:

var services = ['EC2', 'S3', 'RDS', 'IAM']
var promises = [];

for(var i = 0; i < services.length; i++) {
   var promise = awsStatus('us-east-1', services[i])
      promises.push(promise);
      console.log(promises);
}

q.all(promises).then(function(data){
   console.log(promises);
});

it's supposed to loop on the services array with the awsStatus method. 它应该使用awsStatus方法在services数组上循环。 The problem is that sometimes I get all the results I want: 问题是有时我会得到所有想要的结果:

{ service: 'IAM', status: 0 }
{ service: 'EC2', status: 0 }
{ service: 'RDS', status: 0 }

But sometimes I get incomplete results. 但是有时我得到的结果不完整。 I thought I needed .then after awsStatus but that also didn't resolve this. 我认为我需要.then以后awsStatus但也没有解决这个问题。 What else is wrong in this piece of code? 在这段代码中还有什么问题?

since now there's a comment, I've also tried this : 从现在开始有评论,我也尝试过这个:

var services = ['EC2', 'S3', 'RDS', 'IAM']
var promises = [];

for(var i = 0; i < services.length; i++) {
   var promise = awsStatus('us-east-1', services[i]).then(function(promise){
      promises.push(promise);
      //console.log(promises);
});
}
q.all(promises).then(function(data){
   console.log(promises);
});

and it produces the same results. 并产生相同的结果。

Try using .each 尝试使用.each

Promise.each(services, function(service) {
  return awsStatus('us-east-1', service).then(function(promise){
      promises.push(promise);
      //console.log(promises);
  });
}).then(function() {
  console.log('Done with all instances');
});

I can suggest a solution using async library as follows: 我可以建议使用异步库的解决方案,如下所示:

var services = ['EC2', 'S3', 'RDS', 'IAM']
async.map(services, 
  function(item, done){
    awsStatus('us-east-1', item).then(
      function(){
        done(null, "Completed item " + item);
      }, 
      function(err){
        done(err + " in item " + item, null);
      }
    );
  }, 
  function(err, results){
    if(err) return console.log(err);
    console.log(results);
  }
);

It will fail and stop executing if one of the promises returns an error. 如果承诺之一返回错误,它将失败并停止执行。 If dont want to stop you can return null in the error function of promise instead of error message as the first argument of done method 如果不想停止,则可以在promise的错误函数中返回null ,而不是将错误消息作为done方法的第一个参数

There are two problems in your code: 您的代码中有两个问题:

  1. Using q.all() does not guarantee that the code will wait for all the promises to resolve. 使用q.all()不能保证代码将等待所有的诺言得以解决。 If one of them is rejected, the then method would be called, not waiting for the rest of the promises. 如果其中之一被拒绝,则将调用then方法,而不等待其他承诺。 You can solve that by using q.allResolved() instead. 您可以改用q.allResolved()解决此问题。
  2. You are logging the wrong objects. 您正在记录错误的对象。 You should be logging the results of the promises, and not the promise objects themselves. 您应该记录承诺的结果,而不是承诺对象本身。

Example of how to solve both problems: 如何解决这两个问题的示例:

q.allResolved(promises).then(function(results) {
  console.log(results);
}).catch(function(err) {
  console.error(err);
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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