问题
I'm new on AngularJS and JavaScript.
I am getting remote information for each of the elements of an array (cars) and creating a new array (interested prospects). So I need to sync the requests. I need the responses of each request to be added in the new array in the same order of the cars.
I did it first in with a for:
for (a in cars) {
//async request
.then(function () {
//update the new array
});
}
This make all the requests but naturally didn't update the new array.
After seeking in forums, I found this great examples and explanations for returning a intermediate promise and sync all of them.
1. http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html
2. http://stackoverflow.com/questions/25605215/return-a-promise-from-inside-a-for-loop
3. http://www.html5rocks.com/en/tutorials/es6/promises/
(@MaurizioIndenmark, @Mark Rajcok , @Michelle Tilley, @Nolan Lawson)
I couldn't use the Promise.resolve() suggested in the second reference. So I had used $q.defer()
and resolve()
. I guess I have to inject a dependency or something else that I missed. As shown below:
In the Controller I have:
$scope.interestedProspects = [] ;
RequestDetailsOfAsync = function ($scope) {
var deferred = $q.defer();
var id = carLists.map(function (car) {
return car.id;
}).reduce(function (previousValue, currentValue) {
return previousValue.then(function () {
TheService.AsyncRequest(currentValue).then(function (rData) {
$scope.interestedProspects.push(rData);
});
});
}, deferred.resolve());
};
In the Service I have something like:
angular.module('app', []).factory('TheService', function ($http) {
return {
AsyncRequest = function (keyID) {
var deferred = $q.defer();
var promise = authorized.get("somep.provider.api/theService.json?" + keyID).done(function (data) {
deferred.resolve(data);
}).fail(function (err) {
deferred.reject(err);
});
return deferred.promise;
}
}
}
The displayed error I got: Uncaught TypeError: previousValue.then is not a function
I made a jsfiddle reusing others available, so that it could be easier to solve this http://jsfiddle.net/alisatest/pf31g36y/3/. How to wait for AsyncRequests for each element from an array using reduce and promises
I don't know if the mistakes are:
- the place where the resolve is placed in the controller function.
- the way the reduce function is used
The previousValue and currentValue sometimes are seen by javascript like type of Promise initially and then as a number. In the jsfiddle I have a working example of the use of the reduce and an http request for the example.
回答1:
Look at this pattern for what you want to do:
cars.reduce(function(promise, car) {
return promise.then(function(){
return TheService.AsyncRequest(car).then(function (rData) {
$scope.details.push(rData);
});
});
}, $q.when());
This will do all the asynchronous calls for every car exactly in the sequence they are in the cars array. $q.all
may also be sufficient if the order the async calls are made doesn't matter.
回答2:
It seems you are calling reduce
on an array of ids, but assume in the passed function that you are dealing with promises.
In general, when you want to sync a set of promises, you can use $q.all
You pass an array of promises and get another promise in return that will be resolved with an array of results.
来源:https://stackoverflow.com/questions/34115441/how-to-wait-for-asyncrequests-for-each-element-from-an-array-using-reduce-and-pr