我目前的实施是:
getGroupMembersIDsWithID(groupIDs[i]).then(function(memberIDs) {
for (var i in memberIDs) {
[1]
getMemberFirstNameWithID(memberIDs[i]).then(function(firstName) {
[2]
getMemberLastNameWithID(memberIDs[i]).then(function(lastName) {
group.members.push({
id: memberIDs[i],
firstName: firstName,
lastName: lastName
});
});
});
[3]
}
});
调试时,调用顺序为:
[1],[3],[1],[3],[2],[2]
这会在此系统中产生问题,例如,在for
循环中,lastName
的{{1}}实际上将设置为i
lastName
1}}。
我已经实施了承诺,并认为它会起作用,但显然不是:
i + 1
我需要调用的顺序为:
[1],[2],[3],[1],[2],[3]
那么,在回调一个promise之前,停止执行的最佳方法是什么。基本上,所以承诺是阻止。
如果这不是首选的做法(因为我看到有人说你不应该阻止承诺)< / em>,首选方法是什么?
答案 0 :(得分:1)
基本上,承诺是阻止。
基本上不应该这样做。这不是promises / javascript的工作方式。有办法阻止JS(承诺与否),但实际上,这不符合JavaScript的精神。
您最好的做法是将[3]打包成一个函数(我喜欢使用变量):
var three = function() { [3]; }
然后,在适当的时间(可能是最后.then(...)
)调用函数three
。
举个例子:
getGroupMembersIDsWithID(groupIDs[i]).then(function(memberIDs) {
for (var i in memberIDs) {
[1]
var three = function() { [3]; }
getMemberFirstNameWithID(memberIDs[i]).then(function(firstName) {
[2]
getMemberLastNameWithID(memberIDs[i]).then(function(lastName) {
group.members.push({
id: memberIDs[i],
firstName: firstName,
lastName: lastName
});
});
}).then(three); //I think this would be the appropriate spot
}
});
答案 1 :(得分:0)
承诺可以使用。您可以使用$q.all
组合多个承诺。每当你有一个承诺返回它,所以调用函数可以等待被调用函数的承诺。并且不要忘记错误处理 - 在每个级别(使用.then
时)。通过这种方式,他们不会被吞没到某个地方。当然,除非您在某些时候能够进行有意义的错误处理。
我冒昧地改变了你的代码,所以你可以看到可能的东西。这里最重要的是你可以同时发送名字和姓氏请求(我想它们是对服务器的请求),并且不必等待第一个名字的响应,直到你可以开始请求姓氏。
return getGroupMembersIDsWithID(groupIDs[i]).then(function(memberIDs) {
var promises = [],
memberPromises = [];
angular.forEach(memberIDs, function(memberId) {
//[1]
memberPromises = [];
memberPromises.push(getMemberFirstNameWithID(memberId));
memberPromises.push(getMemberLastNameWithID(memberId));
promises.push($q.all(memberPromises).then(function(responses) {
//kind of [2], although resolved only when first AND last name are done
return $q.resolve(group.members.push({
id: memberId,
firstName: responses[0],
lastName: responses[1]
}));
//kind of [3], would have to return later then though
}, function(error) {
return $q.reject(error);
})
});
return $q.all(promises);
}, function(error) {
return $q.reject(error);
});
未经测试,但