所以我有这个功能,我需要结合多个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 ????????
})
});
};
答案 0 :(得分:1)
当你在回调函数中时,你只能依赖promises解决。
var messages = [];
somethingAsync().then(function(data){
messages.push(data);
});
console.log(messages.length)
可能会返回0
或1
,具体取决于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]);
}
});