承诺内部循环等待

时间:2017-07-12 05:57:33

标签: javascript node.js promise q

我有这段代码:

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

它应该使用services方法在awsStatus数组上循环。问题是有时候我得到了我想要的所有结果:

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

但有时我会得到不完整的结果。我认为在.then之后我需要awsStatus,但这也没有解决这个问题。这段代码还有什么问题?

既然现在有评论,我也试过了:

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

并产生相同的结果。

3 个答案:

答案 0 :(得分:1)

尝试使用.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');
});

答案 1 :(得分:0)

我可以使用async库建议解决方案如下:

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

如果其中一个promises返回错误,它将失败并停止执行。如果不想停止,您可以在promise的错误函数中返回null而不是错误消息作为done方法的第一个参数

答案 2 :(得分:0)

您的代码中存在两个问题:

  1. 使用b = [("tomato", "red), ("apple", "red")]并不能保证代码会等待所有要解决的承诺。如果其中一个被拒绝,将调用q.all()方法,而不是等待其余的承诺。您可以使用then来解决此问题。
  2. 您正在记录错误的对象。您应该记录promises的结果,而不是promise对象本身。
  3. 如何解决这两个问题的示例:

    q.allResolved()