Andreas Köberle
Andreas Köberle

Reputation: 110892

Promise that returns a promise

I have nested promise where a function calls another function and both return promises. Function b is calling function a and when the promise of the function a is done function b resolves its own deferred and passing the result from a and its own result.

function a(){
  var d =  $.Deferred();
  makeSomeAsyncCall(function(){
    d.resolve('a')
  })
  return d.promise();
}

function b(){
  var d =  $.Deferred();
  a= a()

  a.done(function(a){d.resolve(a, 'b')})
   .fail(function(a){d.reject(a, 'b')})

  return d.promise();

}

b().done(function(a, b){console.log(a, b)})
 .fail(function(a, b){console.log(a, b)})

I wonder if there is way to wright this without creating a deferred in function b

Upvotes: 2

Views: 356

Answers (2)

Bergi
Bergi

Reputation: 664297

I wonder if there is way to wright this without creating a deferred in function b

Yes, there is. To chain two (potentially asynchronous) functions is the sole purpose of the main promise method,then (in old versions known as pipe). Simply write

function b() {
    return a().then(function success(aresult) {
        return [aresult, "b"];
    }, function error(aerror) {
        return $.Deferred().reject(aerror, "b");
    });
}

I'm not sure whether you actually need that error handler, if you don't specify it then the aerror will be propagated automatically.

Upvotes: 2

Mike Edwards
Mike Edwards

Reputation: 3773

I wonder if there is way to wright this without creating a deferred in function b

No, I don't believe there is. If a manages resolving its own deferred, and b wants to return a deferred that get's two result values, one of which is the result of a, then you must instantiate a new deferred within b.

However, it would be interesting to know exactly why you are structuring it like this given that in your example processing within b() ignores the result of a(). You may want to consider creating deferred results for a and b completely independent of one another then joining them when you invoke them instead of nesting the calls. Using $.when():

$.when(a(), b()).done(function(a,b) {
    // process both results
}).fail(function(a,b) {
    // process both results
});

Written this way b() doesn't need to know anything about a().

Upvotes: 0

Related Questions