Несколько promises из одного запроса $http в AngularJS
Я хотел бы реализовать promises в моем приложении AngularJS, как вы можете видеть в этом примере: qaru.site/info/16303/...
Мое приложение будет принимать несколько массивов данных, делающих несколько обращений к базе данных на моем сервере, но я настроил свой сервер, чтобы вернуть все эти данные в качестве одного ответа в идею минимизации запросов, чтобы мое приложение было как можно более эффективным ( данные по существу бесполезны, если только все данных не попадает на клиент). Поэтому вместо этого...
MyCtrl.resolve = {
projects : function($q, $http) {
return $http.get('/api/projects'});
},
clients : function($q, $http) {
return $http.get('/api/clients'});
}
};
Я хотел бы иметь возможность сделать одиночный $http
запрос GET на URL, например /api/allData
, а затем дать обещание для projects
, которое будет установлено равным allData.projects
и обещание для clients
, которое будет установлено равным allData.clients
и т.д. (где allData
- это данные, которые возвратились с моим единственным запросом). Я все еще очень новичок в promises, может ли кто-нибудь дать мне пример того, как я настроил эти promises внутри MyCtrl.resolve
?
Ответы
Ответ 1
Ну, не так много смысла в использовании двух promises, которые, как вы знаете, представляют собой одно и то же обещание. Но вы действительно можете создать услугу, которая получит ручку, обещание и возвращение двух. Что-то вроде этого:
var mod = angular.module('mod', []);
mod.service('theService', function($q, $http) {
return function() {
var cliDeferred = $q.defer(),
proDeferred = $q.defer();
$http.doYourStuff().then(function _onSuccess(data) {
cliDeferred.resolve(data.clients);
proDeferred.resolve(data.projects);
}, function _onError(err) {
cliDeferred.reject(err);
proDeferred.reject(err);
});
return {clients: cliDeffered.promise, projects: proDeferred.promise};
};
});
Но, как я уже сказал, в этом нет особого смысла. Возможно, лучшее решение, учитывая, что ваша служба вернет массив, вернет объект с пустыми массивами и заполнит их при завершении обещания $http.
Ответ 2
Я считаю, что вы ищете:
var myApp = angular.module('myApp', []);
myApp.factory('myService', function ($http, $q) {
return {
getAllData: function () {
return $q.all([
// $q will keep the list of promises in a array
$http.get('/api/projects'),
$http.get('/api/clients')
]).then(function (results) {
// once all the promises are completed .then() will be executed
// and results will have the object that contains the data
var aggregatedData = [];
angular.forEach(results, function (result) {
aggregatedData = aggregatedData.concat(result.data);
});
return aggregatedData;
});
}
};
});
Вы можете получить свои данные из окончательного массива aggregatedData
(например: aggregatedData[0), aggregatedData [1],...)
Вы можете настроить эти promises внутри MyCtrl.resolve за один раз:
resolve = {
getAllData : myService.getAllData()
}