Reputation: 1119
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
Reputation: 26
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)
.
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