I have a chain of ajax requests that support a series of cascading drop down select lists. When you select a value in the 1st drop down, a request is fired to populate the 2nd, when that is complete (and the drop down filled), the next request fires to populate the 3rd drop down, and so on down the line.
There are some variations to the way these request chains are formed, so I was hoping to assemble the requests using the jQuery Deferred objects.
I see how I can chain the 2nd request to the first, but I don't see how I can chain the third request to the 2nd.
function Step1() { return $.ajax(<foo>);}
function Step2() { return $.ajax(<foo>);}
function Step3() { return $.ajax(<foo>);}
$(function() {
Step1().then(Step2).then(Step3);
});
The intent is that Step3 is triggered when Step2 is resolved, but the deferred object returned by .then(Step2)
is from Step1, so Step3 is added as a callback to Step1.
I think it is clearer what I'm trying to do if you please see this jsFiddle sample. Edit:Here is the same script with a delay added to the second call to make it more obvious.
For error handling I recommend you rewrite Stepn to :
Using callbacks in this format allows you to do what you want. if you have more then 5 steps the indenting becomes a mess and it might be worthwhile to build a queue for this.
Here's a live example
Queue.add([def, def, ...], options)
Adds a defferred item or an array of deferred items to the queue. Can be used with either a single deferred item or an array. The options map is as followsQueue.runItem
, a function that runs the next item in the queue. Called internally, possible to be used manually in concatenation with the delay property.We were fortunate and had some flexibility in the timeline. We ended up using the
.pipe()
chaining added to deferred objects in jQuery 1.6.Thanks to everyone for their help!
I started wrestling with this recently (see my question here), inspired by a blog series by James Coglan.
After messing around with 'monads' for a while, I came back to wishing that it were possible to 'chain' deferred objects together. The problem is that "done" returns the same deferred object, instead of a new one.
I browsed the jquery code for a while, and figured there was no way I could inject anything into the Deferred or _Deferred code. However, it is possible to inject our own object as a parameter to the
promise()
function. So if we create a function which will generate a chainable promise for us......we can then use it to pimp our style:
See the jsfiddle here for the 'before/after' code samples: http://jsfiddle.net/Benjol/DjrRD/