0

I have a resolve promise function that uses $q service, where there is some generic code to resolve/reject based on certain conditions. I have a scenario wherein I would have to execute api2 only after api1 is successfully resolved. But both the calls are happening asynchronously. I have pasted the pseudo code below. Please help. Thanks a lot in advance.

var resolvePromise = function(promise)
{
    var defer = $q.defer();
    promise.then(function(response)
        if(certain conditions are true)
        {
             defer.reject(err)
        }
        defer.resolve();
    )
    .catch(function(errors){
        defer.reject(errors);
    })

   return defer.promise;
}

function synchronousCalls()
{
    var promise1 = service.getApi1();
    var promise2 = service.getApi2();

    return resolvePromise(promise1).then(function(){
          return resolvePromise(promise2);
    })
}

function getData()
{
    synchronousCalls().then(function(){
       console.log("synchronous run of apis ended");
    })
}
mantadt
  • 101
  • 1
  • 15
  • 3
    Don't fire `service.getApi2();` until you are done with `service.getApi1();`. That's your problem. – zero298 Oct 26 '17 at 17:19
  • Remove the line `var promise2 = ...` and then change return to `return resolvePromise(promise1).then(function() { return resolvePromise(service.getApi2()) })`? – CRice Oct 26 '17 at 17:21
  • That `resolvePromise()` function is a mess and totally unnecessary and practices several promise anti-patterns. – jfriend00 Oct 26 '17 at 17:30
  • You appear to be looking for simple "chaining" of asynchronous operations using promises of which there are hundreds of relevant questions and answers already here on stack overflow. – jfriend00 Oct 26 '17 at 17:39
  • Other answers that cover this same topic: [Execute native js promise in series](https://stackoverflow.com/questions/30445543/execute-native-js-promise-in-series/30445733#30445733) and [Understanding Javascript promises: branching and chaining](https://stackoverflow.com/questions/29853578/understanding-javascript-promises-stacks-and-chaining/29854205#29854205) and [ES6 Promise execution order](https://stackoverflow.com/questions/36526639/es6-promise-execution-order/36526710#36526710). – jfriend00 Oct 26 '17 at 17:44
  • Other references: [Prefer way of doing multiple dependent ajax synchronous call](https://stackoverflow.com/questions/33200384/prefer-way-of-doing-multiple-dependent-ajax-synchronous-call/33200417#33200417) and [Run two Ajax calls sequentially](https://stackoverflow.com/questions/33332491/run-two-functions-with-ajax-calls-sequentially/33332528#33332528) and [Sequential execution of promises](https://stackoverflow.com/questions/36649926/sequential-execution-of-promise/36650839#36650839). – jfriend00 Oct 26 '17 at 17:47
  • thank you @jfriend00 for the links. Will have a look at them – mantadt Oct 26 '17 at 17:49

2 Answers2

2

Change the synchronousCalls to

function synchronousCalls()
{
    return service.getApi1().then(resolvePromise).then(service.getApi2).then(resolvePromise);
}
Anthony C
  • 2,117
  • 2
  • 15
  • 26
2

You don't need the resolvePromise function. Have getApi1 and getApi2 return Promises directly that you can .then(). Additionally, calls to functions that return Promises don't stop execution context. You are firing calls to both APIs immediately and not waiting for the first to finish. You need to call to getApi1(), and .then() the Promise that should be returned from it. Consider the following code:

// This says, fire them both immediately
var promise1 = service.getApi1();
var promise2 = service.getApi2();

// Your call should look something like this
service
    .getApi1()
    .then(function (api1Response) {
        // If I'm in here, I know that the request to service 1 is done
        return service
            .getApi2();
    }).then(function (api2Response) {
        // If I'm in here, I know that the request to service 2 is done
        console.log(api2Response);
    })
    .catch(function (err) {
        console.log("Something has gone wrong");
    });

Both of you getApi functions should look something like this, where the main thing they do is return something (like a Promise) with a .then() method.

function getApi1() {
    // This is returning a Promise
    return $http
        .get("some/resource/on/the/server.json")
        .then(function (response) {
            /*
             * Here I'm just peeling out the data from the response
             * because I don't actually care about the details of the
             * response, just the data
             */
            return response.data;
        });
}
zero298
  • 25,467
  • 10
  • 75
  • 100
  • Thank you for the detailed explanation @zero298 – mantadt Oct 26 '17 at 17:50
  • In the spirit of stack overflow, it's best for the community next time if you point the OP to any one of hundreds of relevant other answers by marking the question as a duplicate rather than repeating the same basic content over and over here. I know you were just trying to help, but this is a widely asked question with lots of other questions/answers that are basically duplicates. – jfriend00 Oct 26 '17 at 17:52