tariksbl
tariksbl

Reputation: 1119

Delegating jquery Deferred to another Deferred

I'm trying to chain jquery deferreds such that a promise is resolved by another Deferred.

My use case is: I have an object that returns a promise to a client,

var p1 = $.Deferred();

// client gets a promise for a future result
function get() {
    return p1.promise();    
}

At some time in the future, something else delivers the result that p1 should ultimately resolve to as either a value, or another promise:

// at some time in the future, something else completes p1 with either a value:
function resolveWithValue(val) {
    p1.resolve(val);
}

// .. or with a promise
function resolveWithPromise(promise) {
    // ... in which case we want p1 to resolve/reject/wait based on the promise arg:

    // 1st try - doesn't work - p1.done() yields a promise, not the promise's value;
    p1.resolve(promise);

    // 2nd try - this works, but-- is there a better syntax?
    promise
        .done(function(v) { p1.resolve(v); })
        .fail(function() { p1.reject(); });
}

My question is, is there a better syntax for that last line ('2nd try')? I believe other promise libs allow chaining like in '1st try' but I need $.Deferred() here.

I'm not looking for advice on how to restructure the code to avoid the chaining, I can't change it (nor can I share it, thus the contrived example).

Upvotes: 1

Views: 271

Answers (1)

mrand
mrand

Reputation: 26

Chaining Deferreds

If you want to treat p1 as a delegate of p2, connect them like so:

p2.then(p1.resolve, p1.reject, p1.notify)

Then, for example, if you call p2.resolve(x), it will call p1.resolve(x).

Why would you do this?

One concrete example: calling $.get() from inside a setTimeout callback, inside a helper function:

// Sends a GET request to `url` after `delayMs`.
// Returns a jQuery promise.
function startDelayedRequest(url, delayMs) {
    var p1 = new $.Deferred();
    setTimeout(function() {
        var p2 = $.get(url);
        p2.then(p1.resolve, p1.reject, p1.notify);
    }, delayMs);
    return p1;
}

Upvotes: 1

Related Questions