问题
I have already read some articles and questions about promises but I still have problems to get my head around them. Here's what I want to do:
My application should request properties from a device. The properties can be represented as single value or as an Array. Every property has attributes, that give me information about it (like is it an array, is it writeable, etc.).
So my first attempt was to read the attributes of an property first. So I can see if I need to read a single value or an Array (for example).
Everything is working with websockets, so I'm not using angulars $http service.
var valueRequests = [];
angular.forEach(properties, function (property, key) {
requestPropertyAttributes(property).then(function (result) {
if (result.isList) {
valueRequests.push(requestPropertyList(property));
}
else {
valueRequests.push(requestPropertyValue(property));
}
});
});
$q.all(valueRequests).then(function () {
//do sth. after all data was read
});
Well, all I got with this are some errors (it reads list where are values and/or vice versa) and $q.all() does not fire.
My request Functions are returning promises.
Is this the correct attempt or have I failed somewhere? As said I'm not really sure with promises, so I may have a problem of understanding the mechanism here.
Thanks for any help :)
回答1:
You need to do a return of the inner promise inside the first then
, and then add that promise to the list.
var valueRequests = [];
angular.forEach(properties, function (property, key) {
valueRequests.push(requestPropertyAttributes(property).then(function (result) {
if (result.isList) {
return requestPropertyList(property);
}
else {
return requestPropertyValue(property);
}
}));
});
$q.all(valueRequests).then(function () {
//do sth. after all data was read
});
回答2:
It's a little unclear what exactly you are attempting. However, I think you need to change your code as follows:
var valueRequests = [];
angular.forEach(properties, function (property, key) {
valueRequests.push(requestPropertyAttributes(property).then(function (result) {
if (result.isList) {
return requestPropertyList(property);
}
else {
return requestPropertyValue(property);
}
}));
});
$q.all(valueRequests).then(function () {
//do sth. after all data was read
});
This should ensure that the then attached to the $q.all does not fire until all other promises are resolved. If you return a promise from a then(...) function, then(...) returns that promise. Otherwise it creates a promise and returns that instead, which is not related to your web request.
来源:https://stackoverflow.com/questions/26362295/chaining-subsequent-promises-and-wait-for-all-to-resolve