Multiple promises from single $http request in Ang

2019-05-11 14:06发布

I would like to implement promises in my AngularJS application like you can see in this example: https://stackoverflow.com/a/12360882/371273

My application will take multiple arrays of data making multiple database hits on my server, but I have configured my server to return all of that data as one response in the idea of minimizing requests to keep my application as efficient as possible (the data is essentially useless unless all of the data gets to the client). So instead of doing this...

MyCtrl.resolve = {
    projects : function($q, $http) {
        return $http.get('/api/projects'});
    },
    clients : function($q, $http) {
        return $http.get('/api/clients'});
    }
};

I would like to be able to make a single $http GET request to a URL like /api/allData, and then have a promise for projects that will be set equal to allData.projects and a promise for clients that will be set equal to allData.clients, etc. (where allData is the data that came back with my single request). I'm still very new to promises, can someone give me an example of how I would set up these promises inside MyCtrl.resolve?

2条回答
霸刀☆藐视天下
2楼-- · 2019-05-11 14:12

Well, there is not much of a point in using two promises that you know represent the same promise. But you could indeed create a service that receive handles the one promise and return two. Something like this:

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

But as I said, there is not much of a point in this. Maybe a better solution, considering your service will return an array, would be return an object with empty arrays and fill them when the $http promise gets completed.

查看更多
\"骚年 ilove
3楼-- · 2019-05-11 14:28

I believe that's what you are looking for:

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

The you can get your data from the final aggregatedData array (e.g.:aggregatedData[0], aggregatedData[1],...)

You can set up these promises inside MyCtrl.resolve in a single call:

resolve = {
    getAllData : myService.getAllData()
}
查看更多
登录 后发表回答