AngularJS -等待多个资源查询完成。

时间:2021-10-22 11:48:02

I have a single factory defined with ngResource:

我有一个用ngResource定义的工厂:

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

I am making multiple calls to the query method defined on this factory. The calls can happen asynchronously, but I need to wait for both calls to complete before continuing:

我正在对这个工厂定义的查询方法进行多次调用。调用可以异步发生,但我需要等待两个调用完成后才能继续:

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

Is there a way to do this with AngularJS factories defined with ngResource, similar to jQuery's $.when().then() functionality? I would prefer not to add jQuery to my current project.

是否有一种方法可以在用ngResource定义的AngularJS工厂中实现这一点,类似于jQuery的$ when().then()功能?我不希望在当前项目中添加jQuery。

3 个解决方案

#1


190  

You'll want to use promises and $q.all().

您将希望使用承诺和$q.all()。

Basically, you can use it to wrap all of your $resource or $http calls because they return promises.

基本上,您可以使用它来包装所有的$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...
});

#2


16  

I think a better solution is:

我认为更好的解决办法是:

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

#3


10  

The solution from Ben Lesh is the best but it's not complete. If you need to handle error conditions--and, yes, you do--then you must use the catch method on the promise API like this:

Ben Lesh的解决方案是最好的,但还没有完成。如果您需要处理错误条件——是的,您需要处理——那么您必须在promise API上使用catch方法,如下所示:

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

});

If you don't define catch and all of your promises fail, then the then method won't ever execute and thus will probably leave your interface in a bad state.

如果您没有定义catch,并且您的所有承诺都失败了,那么then方法将永远不会执行,因此可能会使您的接口处于糟糕的状态。

#1


190  

You'll want to use promises and $q.all().

您将希望使用承诺和$q.all()。

Basically, you can use it to wrap all of your $resource or $http calls because they return promises.

基本上,您可以使用它来包装所有的$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...
});

#2


16  

I think a better solution is:

我认为更好的解决办法是:

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

#3


10  

The solution from Ben Lesh is the best but it's not complete. If you need to handle error conditions--and, yes, you do--then you must use the catch method on the promise API like this:

Ben Lesh的解决方案是最好的,但还没有完成。如果您需要处理错误条件——是的,您需要处理——那么您必须在promise API上使用catch方法,如下所示:

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

});

If you don't define catch and all of your promises fail, then the then method won't ever execute and thus will probably leave your interface in a bad state.

如果您没有定义catch,并且您的所有承诺都失败了,那么then方法将永远不会执行,因此可能会使您的接口处于糟糕的状态。