0

I have about 5 requests that are made when my view loads. This is for an edit form:

var reqA = function() {...};
var reqB = function() {...};
var reqC = function() {...};
var reqD = function() {...};
var reqE = function() {...};

Now I want reqA() and reqB() to load asynchronously and if possible return a single promise.

reqC() and reqD() should only load after reqA() and reqB() have finished and executed their promise.

reqE() should only load after reqC() and reqD().

This is what I want to do, however I have no idea how to go about it. I can load them all asynchronously or one after another by chaining promises but not in the way I want.

halfer
  • 19,824
  • 17
  • 99
  • 186
user3718908x100
  • 7,939
  • 15
  • 64
  • 123

2 Answers2

2

If your functions all use the $http provider, it is easy to accomplish. You will want to modify your functions to return the result of the $http call like this

function reqA() {
  return $http.get(...);
}

Now that they are returning promises, you can easily use the $q provider to orchestrate your requests:

$q.all([reqA(), reqB()])
.then( () => 
  $q.all([reqC(), reqD()])
  .then(() => reqE()) 
 );

For regular JS (non ES6):

$q.all([reqA(), reqB()])
.then(function() {
  $q.all([reqC, reqD()])
  .then(function() {
    reqE();
  });
});

If you don't want to return the result of $http in your functions, you will need to set them up to return a promise in one way or the other:

function reqA() {
  var deferred = $q.defer();
  ... your request code ...
  // call this if everything is ok
  deferred.resolve();
  // call this if there was an error
  deferred.reject();
  return deferred.promise;
}
Pop-A-Stash
  • 6,572
  • 5
  • 28
  • 54
0

Here is an example that you can take a look at that might make it clearer. It makes use of Promise which is globally available in almost all javascript environments (excluding IE and older node versions).

   angular
  .module('example', [])
  .run(function($q) {
    function requestOne() {
      return $q.when("one")
    }

    function requestTwo() {
      return $q.when("two")
    }

    function requestThree() {
      return $q.when("three")
    }

    function requestFour() {
      return $q.when("four")
    }

    function requestFive() {
      return $q.when("five")
    }

    $q
      .all([requestOne(), requestTwo()])
      .then(function(responses){
        console.log(responses[0] === "one");
        console.log(responses[1] === "two");

        return $q.all([requestThree(), requestFour()]);
      })
      .then(function(nextResponses){
        console.log(nextResponses[0] === "three");
        console.log(nextResponses[1] === "four")

        return requestFive();
      })
      .then(function(lastResponse){
        console.log(lastResponse === "five")
      })
});

angular.element(document).ready(function() {
    angular.bootstrap(document, [ 'example' ]);
});

I assume that you are using angular 1, if you aren't there Promise is available in the global scope in almost all environments.

mkalish
  • 330
  • 2
  • 8