David Dahan
David Dahan

Reputation: 11192

Chaining web services calls with promises does not always work

I'm facing an troublesome issue, because it does not occurs every time: I call webservices with angularJS (hosted in Django/Tastypie), with promises sothat WS2 (Web Service #2) is called only when WS1 has been successfully executed, etc.

The code looks like this:

myfunc = function() {
    callPromiseWS1()
    .then(function(data){
        callPromiseWS2()
    })
    .then(function(data){
        callPromiseWS3()
    })
};

Sometimes (and not always), WS3 fails because the object that should have been already created by WS2 does NOT exist.

Of course, if I try to execute the WS3 request later manually, it works.

I have the feeling that WS2 and WS3 are executed in parallel, that's not what I expect.

Any idea? Thank you.

Upvotes: 0

Views: 520

Answers (2)

JLRishe
JLRishe

Reputation: 101758

You're missing 3 return statements, but the behavior you're experiencing is because of one in particular:

myfunc = function() {
    return callPromiseWS1()
    .then(function(data){
        return callPromiseWS2();        // this one
    })
    .then(function(data){
        return callPromiseWS3();
    })
};

If you don't return the promise that callPromiseWS2 returns, the then() won't know that it's dealing with a promise and just move onto the next then as soon as the synchronous code in callPromiseWS2 completes.

Note that if you're not actually using the data parameter in each step (or if you're just going to pass it right into callPromiseWS2 and callPromiseWS3 as the only parameter), you can simplify this and eliminate the need for two of the above return statements and a lot of the code:

myfunc = function() {
    return callPromiseWS1()
    .then(callPromiseWS2)
    .then(callPromiseWS3);
};

Remember that any function that uses promises should either return the promise, or call .done() at the end.

As a matter of personal preference, I think it's a good idea to use a naming scheme for functions that return promises so that you know they return a promise that needs to be dealt with.

Upvotes: 3

Polmonite
Polmonite

Reputation: 943

I'm not an expert on promises (and maybe the code you posted was simplified), but the first thing I would check is that the first then returns something, or the second .then will have the same object returned by callPromiseWS1() to work on. I believe it should be something like:

callPromiseWS1()
    .then(function(data){
        return callPromiseWS2();
    })
    .then(function(data){
        return callPromiseWS3();
    })

But, as I said, I'm not an expert on promises and I don't know if it was just a simplified example of your structure.

Upvotes: 2

Related Questions