Я написал специальный сервис http, который выглядит примерно так:
.service('httpCaller', function ($http, $location) {
var url = 'myURL'
var http = {
async: function (api) {
var promise = $http({
method: 'GET',
url: url + api,
dataType: 'json'
})
.success(function (call) {
return call;
})
.error(function () {
$location.path('/search');
});
return promise;
}
};
return http;
});
И мне нужно вызвать эту услугу в цикле примерно в сто раз так:
var results = [];
for (var i = 0; i < someArray.length; i++) {
httpCaller.async('myAPI').then(function (data) {
results.push(data);
});
}
console.log(results);
Очевидно, мне нужно дождаться завершения каждого HTTP-вызова до начала следующего вызова, иначе, когда я запишу 'результаты' в консоль, он всегда будет пустым, потому что вызовы еще не закончены. Я считаю, что мне нужно использовать...
$q.all()
... но я не могу понять из Angular документации, как интегрировать это с кодом, который я написал. Может ли кто-нибудь объяснить, как мне нужно это делать?
Вы должны сохранить все свои обещания в массиве и передать его функции $q.all
. Затем вы можете определить несколько обратных вызовов, которые автоматически вызываются.
Вот пример.
var results = [],
promises = [];
var promiseSuccess = function (data) {
results.push(data);
};
var allSuccess = function (data) {
//data contains array of all return values for promises
};
for (var i = 0; i < someArray.length; i++) {
promises.push(httpCaller.async('myAPI').then(promiseSuccess));
}
$q.all(promises)
.then(allSuccess) // called when everything has been loaded
Вы можете использовать менеджер обещаний $ q.defer(), от отложенного API.
$ q.defer() получить 2 метода:
Решение (значение): которые разрешают наше совместное обещание, давая ей окончательное значение
reject (причина): которые разрешают ошибку обещания.
Таким образом, вы можете хранить все свои обещания в массиве, затем $q.all()
используется для создания обещания, которое будет разрешено, когда все обещания таблицы, переданные как параметр, сами будут разрешены.
контроллер
(function(){
function Controller($scope, Service, $q) {
var promises = [];
var defer = $q.defer();
//Process loop
for (var i = 0; i < 20; ++i){
//Fill my promises array with the promise that Service.get() return
promises.push(Service.get());
}
//Resolve all promise into the promises array
$q.all(promises).then(function(response){
//Create arr by maping each data field of the response
var arr = response.map(function(elm){
return elm.data;
});
//Resolve my data when she is processed
defer.resolve(arr);
});
//When the data is set, i can get it
defer.promise.then(function(data){
//Here data is an array
console.log(data)
});
}
angular
.module('app', [])
.controller('ctrl', Controller);
})();
обслуживание
(function(){
function Service($http){
function get(num){
//Just an example, we return a promise
return $http.get('path_to_url');
}
var factory = {
get: get
};
return factory;
}
angular
.module('app')
.factory('Service', Service);
})();
error
,error
и,finally
, используется, когда успех возвращает еще одно обещание, я обновил мой пример кода.