Я использую Angular 1.5.8. Представления в моем приложении требуют разных комбинаций из тех же 3 запросов ajax. Некоторые представления требуют данных от всех трех, другие требуют данных от двух или даже одной конечной точки.Цепочка Несколько дополнительных запросов Async Ajax
Я работаю над функцией, которая будет управлять извлечением этих данных, требуя, чтобы приложение только вызывало каждую конечную точку один раз. Я хочу, чтобы запросы ajax вызывались по мере необходимости, но только при необходимости. В настоящее время я создал функцию, которая работает, но, похоже, она может использовать улучшения.
Следующая функция содержится в пределах $rootScope
. Он использует функцию fetchData()
для циклического прохождения запросов на получение по запросу. Когда данные извлекаются, они сохраняются в глобальной переменной $ rootScope.appData, а затем fetchData()
вызывается снова. Когда все данные извлекаются, отложенное обещание разрешается, и данные возвращаются контроллеру.
$rootScope.appData = {};
$rootScope.loadAppData = function(fetch) {
var deferred = $q.defer();
function getUser() {
$http
.get('https://example.com/api/getUser')
.success(function(result){
$rootScope.appData.currentUser = result;
fetchData();
});
}
function getPricing() {
$http
.get('https://example.com/api/getPricing')
.success(function(result) {
$rootScope.appData.pricing = result;
fetchData();
});
}
function getBilling() {
$http
.get('https://example.com/api/getBilling')
.success(function(result) {
$rootScope.appData.billing = result;
fetchData();
});
}
function fetchData() {
if (fetch.user && !$rootScope.appData.currentUser) {
getUser();
} else if (fetch.pricing && !$rootScope.appData.pricing) {
getPricing();
} else if (fetch.billing && !$rootScope.appData.billing) {
getBilling();
} else {
deferred.resolve($rootScope.appData);
}
}
if ($rootScope.appData.currentUser && $rootScope.appData.pricing &&$rootScope.appData.billing) {
deferred.resolve($rootScope.appData);
} else {
fetchData();
}
return deferred.promise;
};
Объект fetch
представлен как атрибут, этот объект показывает, какие Ajax запросы на вызов. Пример вызова к $rootScope.loadAppData()
где будет запрашиваться только пользователя и данные о ценах будет выглядеть следующим образом:
$rootScope.loadAppData({user: true, pricing: true}).then(function(data){
//execute view logic.
});
Я интересно:
- Если сцепление этих функций можно сделать иначе? Достаточно ли функция
fetchData()
, или это странный способ выполнить эту функцию? - Есть ли способ вызвать все необходимые запросы Ajax одновременно, но дождаться завершения всех необходимых вызовов до разрешения обещания?
- Необычно хранить данные как в
$rootScope
?
Я знаю, что эта функция в настоящее время неправильно обрабатывает ошибки. Это функциональность, которую я добавлю перед использованием этого фрагмента, но не имеет отношения к моему вопросу.
Спасибо за этот ответ. Прочитав ваш ответ/сделав больше исследований, для меня совершенно очевидно, что эта логика должна содержаться в сервисе. Я сделал это изменение в своем проекте сейчас. Знаете ли вы, как выполнить все требуемые вызовы параллельно, а не последовательно, а затем вернуть результат, когда какой-либо вызов займет больше времени? – kravse
Используйте '$ q.all', чтобы делать XHR параллельно. Последовательный метод полезен, когда следующий XHR зависит от информации из предыдущего XHR. Примером может служить расчет стоимости доставки после извлечения местоположения пользователей. – georgeawg