Alan De Smet
Alan De Smet

Reputation: 1770

Chaining promises/Deferreds with .then() in jQuery

I'm using jQuery 1.8.3 I have a function that returns a new jQuery.Deferred(). When I chain calls to this function using deferred.then(), based on the documentation, I would expect a given function to be called when the preceding function returns, and to receive the jQuery.Deferred() as input.

In practice a given function is called when the preceding function's jQuery.Deferred() is signaled with deferred.resolve(), and receives the value passed to .resolve().

The actual behavior is what I want, but I'm worried I'm relying on undocumented/unsupported behavior, or that I've actually got a bug creating the illusion of what I want.

For example, given

function async_task(i) {
  console.log("Starting async_task(" + i + ")\n");
  var def = $.Deferred();
  setTimeout(function() {
    console.log("    finished " + i + "\n");
    def.resolve(i + 1);
  }, 1000);
  return def;
}

console.log("starting\n");
var p;
p = async_task(1);
p = p.then(async_task);
p = p.then(async_task);
p.then(function() {
  console.log("done\n");
});

the output is

starting
Starting async_task(1)
    finished 1
Starting async_task(2)
    finished 2
Starting async_task(3)
    finished 3
done

but I would expect

starting
Starting async_task(1)
    finished 1
Starting async_task(2)
Starting async_task([object Object])
done
    finished 2
    finished [object Object]

I can certainly imagine that jQuery is probing what the function passed to .then() returns, and if it's a deferred/promise doing what I want, but I can't find documentation supporting that idea.

Why do my expectations based on the documentation not agree with what I'm observing? Have I overlooked documentation? Is this undocumented behavior I shouldn't rely on? Do I actually have a bug?

Upvotes: 1

Views: 1407

Answers (1)

Bergi
Bergi

Reputation: 664297

Looks like you just misread the docs. Admittedly they could be written better.

The sentence you were missing is

These filter functions can return a new value to be passed along to the promise's .done() or .fail() callbacks, or they can return another observable object (Deferred, Promise, etc) which will pass its resolved / rejected status and values to the promise's callbacks.

While not explained great by jQuery, this adoption ("unwrapping") of further promises is actually one of the outstanding features of promises.

Upvotes: 4

Related Questions