AngularJS - birden fazla kaynak sorgusunun tamamlanmasını bekleyin


105

NgResource ile tanımlanan tek bir fabrikam var:

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

Bu fabrikada tanımlanan sorgu yöntemine birden çok çağrı yapıyorum. Çağrılar eşzamansız olarak gerçekleşebilir, ancak devam etmeden önce her iki çağrının da tamamlanmasını beklemem gerekiyor:

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
    };
});

JQuery'nin $ .when (). Then () işlevine benzer şekilde ngResource ile tanımlanan AngularJS fabrikalarında bunu yapmanın bir yolu var mı? Mevcut projeme jQuery eklememeyi tercih ederim.

Yanıtlar:


201

Sözleri ve $ q.all () ' ı kullanmak isteyeceksiniz .

Temel olarak, tüm $ resource veya $ http çağrılarınızı sözler döndürdükleri için sarmalamak için kullanabilirsiniz.

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...
});

17
Kaynaklar vaatleri geri vermez, gelecekte doldurulacak nesneleri iade ederler. Bununla birlikte, kararsız 1.1.3 sürümünde, kaynaklar da özelliğe sahiptir $thenancak herhangi bir vaat nesnesini açığa çıkarmaz. Maruz bırakmak $promise1.1.4 olacağını tamamen
Umur Kontacı

@ UmurKontacı Bu maalesef 1.1.4 açısal değil !
nh2

Kaynaklarla ilgili ayrıntılar söz konusu değildir , bu konu başlığında ve bu çekme talebinde bulunabilir .
nh2

1
Bu cevap , uygulandıktan sonra nasıl yazılacağını gösterir.
nh2

3
Cevabınız çok yardımcı ve kaynakları güncel açıda vaatlere dönüştürmenin en mantıklı yolu olduğuna inanıyorum. Bağlandığınız belgelerine $q, sonuç dizisinin promise dizisiyle aynı sırada olmasını garanti ettiğini eklemek yararlı olabilir .
nh2

20

Bence daha iyi bir çözüm:

$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...
});

1
Benim için sonunda $ promise olmadan çalıştı ... Tıpkı: Account.query ({type: 'faturalandırma'}), Account.query ({type: 'shipping'})
georgeos

12

Ben Lesh'in sunduğu çözüm en iyisidir ancak tamamlanmamıştır. Hata koşullarını halletmeniz gerekiyorsa - ve evet, yaparsınız - o zaman catchsöz konusu API'deki yöntemi şu şekilde kullanmanız gerekir :

$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...

});

Tanımlamazsanız catchve tüm sözleriniz başarısız olursa, o zaman thenyöntem hiçbir zaman uygulanmaz ve bu nedenle muhtemelen arayüzünüzü kötü bir durumda bırakır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.