2015-04-27 215 views
2

所以我有這個功能,我需要結合多個承諾響應,但一些閱讀後,我意識到承諾是異步,所以在這種情況下,我的循環將完成之前所有的答覆做。我應該在這種情況下需要使用$ 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 ???????? 
    }) 
    }); 
}; 

回答

0

沒有一個工作的例子,很難完全理解你的代碼的上下文,但你可以做類似的事情。

基本想法是創建一個需要等待的承諾列表。此列表中的每個承諾都應返回一個結果(大概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]); 
    } 
}); 
+0

這工作得很好!謝謝! –

1

只能靠承諾當你在裏面的回調函數已經解決。

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

可能返回01取決於長somethingAsync如何進行;你不能依靠它完成。

相反,你應該從做你的調試中回調函數:

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

這將始終返回1