AngularJS: attendere il completamento di più query di risorse

Ho una singola fabbrica definita con ngResource:

App.factory('Account', function($resource) { return $resource('url', {}, { query: { method: 'GET' } }); }); 

Sto facendo più chiamate al metodo di query definito su questo stabilimento. Le chiamate possono avvenire in modo asincrono, ma devo aspettare che entrambe le chiamate siano completate prima di continuare:

 App.controller('AccountsCtrl', function ($scope, Account) { $scope.loadAccounts = function () { var billingAccounts = Account.query({ type: 'billing' }); var shippingAccounts = Account.query({ type: 'shipping' }); // wait for both calls to complete before returning }; }); 

C’è un modo per farlo con le fabbriche AngularJS definite con ngResource, in modo simile alla funzionalità $ .when (). Then () di jQuery? Preferirei non aggiungere jQuery al mio progetto attuale.

Ti consigliamo di utilizzare le promesse e $ q.all () .

Fondamentalmente, puoi usarlo per avvolgere tutte le tue chiamate $ risorse o $ http perché restituiscono promesse.

 function doQuery(type) { var d = $q.defer(); var result = Account.query({ type: type }, function() { d.resolve(result); }); return d.promise; } $q.all([ doQuery('billing'), doQuery('shipping') ]).then(function(data) { var billingAccounts = data[0]; var shippingAccounts = data[1]; //TODO: something... }); 

Penso che una soluzione migliore sia:

 $q.all([ Account.query({ type: 'billing' }).$promise, Account.query({ type: 'shipping' }).$promise ]).then(function(data) { var billingAccounts = data[0]; var shippingAccounts = data[1]; //TODO: something... }); 

La soluzione di Ben Lesh è la migliore ma non è completa. Se hai bisogno di gestire le condizioni di errore – e, sì, lo fai – allora devi usare il metodo catch sull’API di promise come questa:

 $q.all([ doQuery('billing'), doQuery('shipping') ]).then(function(data) { var billingAccounts = data[0]; var shippingAccounts = data[1]; //TODO: something... }).catch(function(data) { //TODO: handle the error conditions... }).finally(function () { //TODO: do final clean up work, etc... }); 

Se non definisci il catch e tutte le tue promesse falliscono, allora il metodo then non verrà mai eseguito e quindi probabilmente lascerà la tua interfaccia in cattivo stato.