AngularJS-여러 리소스 쿼리가 완료 될 때까지 기다립니다.


105

ngResource로 정의 된 단일 공장이 있습니다.

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

이 팩토리에 정의 된 쿼리 메서드를 여러 번 호출하고 있습니다. 호출은 비동기 적으로 발생할 수 있지만 계속하기 전에 두 호출이 모두 완료 될 때까지 기다려야합니다.

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의 $ .when (). then () 기능과 유사하게 ngResource로 정의 된 AngularJS 팩토리로이를 수행하는 방법이 있습니까? 현재 프로젝트에 jQuery를 추가하고 싶지 않습니다.

답변:


200

promises 및 $ q.all () 을 사용하고 싶을 것 입니다.

기본적으로 $ resource 또는 $ http 호출이 promise를 반환하기 때문에 모든 $ resource 또는 $ http 호출을 래핑하는 데 사용할 수 있습니다.

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
자원은 약속을 반환하지 않고 미래에 채워질 객체를 반환합니다. 그러나 불안정한 1.1.3 버전에서는 리소스에도 $then속성이 있지만 promise 개체를 노출하지 않습니다. $promise완전히 노출 되는 것은 1.1.4
Umur Kontacı 2013 년

@ UmurKontacı 이것은 불행히도 각도 1.1.4가 아닙니다 !
nh2 2013-04-30

리소스 에 대한 자세한 내용은 이 스레드 와이 풀 리퀘스트 에서 찾을 수 있습니다 .
NH2

1
이 답변 은 구현 된 후 작성하는 방법을 보여줍니다.
NH2

3
귀하의 답변은 매우 유용하며 자원을 현재 각도에서 약속으로 변환하는 가장 합리적인 방법이라고 생각합니다. $q링크 한의 문서에 결과 배열이 promise 배열과 동일한 순서임을 보장한다는 점 을 추가하면 도움이 될 수 있습니다 .
nh2

20

더 나은 해결책은 다음과 같습니다.

$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
저를 위해 마지막에 $ promise없이 일했습니다 ... 예 : Account.query ({type : 'billing'}), Account.query ({type : 'shipping'})
georgeos

12

Ben Lesh의 솔루션이 최고이지만 완전하지는 않습니다. 오류 조건을 처리해야하는 경우 (예, 그렇습니다) 다음 catch과 같이 promise API 에서 메서드를 사용해야합니다 .

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

});

정의하지 않고 catch모든 약속이 실패하면 then메서드가 실행되지 않으므로 인터페이스가 잘못된 상태로 남게됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.