循环在所有承诺响应之前完成

时间:2015-04-27 23:53:50

标签: javascript angularjs

所以我有这个功能,我需要结合多个promises响应,但经过一些阅读后我意识到promises是异步的,所以在这种情况下我的循环将在所有响应之前完成。在这种情况下,我是否需要使用$ q.all之类的东西?我该如何改进这段代码?感谢..

$scope.messages = [];

function getPastMessages(data) {
  angular.forEach(data, function(item) {            
    Message.get(item.id).then(function(msg) {
      if (msg.data.is_private === false) {
        User.getPictures(msg.data.user.id).then(function(pics) {
          msg.data.user.pictures = pics.data;
        });
      } else {
        User.get(msg.data.im.sender).then(function(sender) {
          msg.data.im.sender = sender.data;
          User.get(msg.data.im.reciever).then(function(reciever) {
            msg.data.im.reciever = reciever.data;
          });                       
        });
      }
      console.log(msg.data); // SHOW 4 OBJECTS CORRECT
      $scope.messages.push(msg.data);
      console.log($scope.messages); // SHOW ARRAY OF 6 OBJECTS    ????????
    })
  });
};

2 个答案:

答案 0 :(得分:1)

当你在回调函数中时,你只能依赖promises解决。

var messages = [];
somethingAsync().then(function(data){
  messages.push(data);
});
console.log(messages.length)

可能会返回01,具体取决于async所需的时间长度;你不能完全依赖它。

相反,你应该从里面的回调函数进行调试:

var messages = [];
somethingAsync().then(function(data){
  messages.push(data);
  console.log(messages.length)
});

这将始终返回1

答案 1 :(得分:0)

如果没有一个工作示例,很难完全理解代码的上下文,但是你可以做类似的事情。

基本思路是创建一个需要等待的承诺列表。此列表中的每个promise都应返回一个结果(大概是msg.data)。使用$q.all,您将在结尾处获得结果列表(每个承诺中的一个)。请注意,.then内返回的内容如果尚未承诺,则会包含在承诺中。

$scope.messages = [];

function getPastMessages(data) {
  var promises = [];
  angular.forEach(data, function(item) {            
    promises.push(getMessage(item));
  });
  return $q.all(promises);
}

function getMessage(item) {
  return Message.get(item.id).then(function(msg) {
    if (msg.data.is_private === false) {
      return User.getPictures(msg.data.user.id).then(function(pics) {
        msg.data.user.pictures = pics.data;
        return msg.data;
      });
    } else {
      return User.get(msg.data.im.sender).then(function(sender) {
        msg.data.im.sender = sender.data;
        return User.get(msg.data.im.reciever).then(function(reciever) {
          msg.data.im.reciever = reciever.data;
          return msg.data;
        });                       
      });
    }
  });
}

用法:

getPastMessages(data).then(function(results) {
  for (var i = 0; i < results.length; i++) {
    $scope.messages.push(results[i]);
  }
});
相关问题