6

I have been testing the new deferred AJAX functions in jquery 1.5 and am impressed with their simplicity and power. There's a larger question I have related to the best way to queue up these requests.

I have two scenarios: serial and parallel, if you will. I want to avoid the sync/async terms because I do want all of these to be asynchronous requests so the user can perform other actions while waiting for the queue to process. I then want to call a single function when the queue has completed processing.

In "serial mode" having two requests I would want them processed as follows:

RequestA -> ResponseA -> RequestB -> ResponseB -> EndOfQueue

In "parallel mode" with two requests I want this result:

RequestA -> RequestB (ResponseA, ResponseB processed whenever ready) -> EndOfQueue

In either case, if any Request fails I would want the queue to stop and pass control to a failure function.

I have requirements that specify a dynamic queue length so I don't think I'll be able to just string a bunch of .then() or .when() deferreds together as I won't know if it's one or one hundred items. I'm executing business logic on a server via a vendor's API so server-side batching will be difficult as I don't have control over that code.

I have built test cases that perform the "parallel" case and call the when() function after all have successfully completed, but these tests aren't dynamic in queue length and aren't portable to the serial model.

I can see how I could create a custom queue object to handle this, but it seems like all of the parts are already written for me in jquery (?). I've looked, but haven't found an example that covers sequential requests in this way.

Any thoughts on how to handle this with the jquery queue/deferred functionality?

Graham
  • 7,431
  • 18
  • 59
  • 84

3 Answers3

4

The simplest way to achieve your RequestA -> ResponseA -> RequestB -> ResponseB order would be using something like this:

var queue = [];

function qNext() {
    $.ajax(queue.shift()).success(qNext);
}

function qAjax(options) {
    queue.push(options);
}

qAjax({
    // $.ajax options
});

qAjax({
    // $.ajax options
});

qNext();

See DEMO.

This is a somewhat simplified version of your requirements but it would be easy to add a callback to run after the queue is empty.

Are you sure you don't want the order of RequestA -> RequestB -> ResponseA -> ResponseB?

rsp
  • 107,747
  • 29
  • 201
  • 177
  • Thanks! I'll give this a shot. In this application we need to make sure that Request B is not started before Response A is received, as there are usually dependencies on A's results in B's instructions. – Graham Mar 15 '11 at 21:08
  • @Graham: Watch the [Asynchronous Iteration Patterns](http://nodetuts.com/tutorials/19-asynchronous-iteration-patterns.html) tutorial by Pedro Teixeira. He talks about Node.js but those patterns can be used in any JavaScript code. I think you might find some useful tricks there that could help you with what you're trying to do. I completely forgot about it when I was writing my answer. – rsp Mar 15 '11 at 21:20
  • Very interesting, thank you (again) for that link. I'm getting some good ideas on how I can build a custom ajax queue object. – Graham Mar 15 '11 at 21:42
1

Please refer to the two questions I asked

  1. jQuery Deferred not working
  2. jQuery.when understanding

Hopefully you should be able to understand the concept.

Community
  • 1
  • 1
Ashish
  • 2,544
  • 6
  • 37
  • 53
0

See this comment on .when() method from deferred AJAX functions

Community
  • 1
  • 1
Dmitry Evseev
  • 11,533
  • 3
  • 34
  • 48
  • Yes, I actually used that example to set up my test cases with when() earlier. My question is about how to use those with a dynamic number of ajax requests. Thanks! – Graham Mar 15 '11 at 20:30
  • mmm... I though about apply, but can't find a way to pass functions execution statements as arguments. If there is such way, it'll look like that `$.when.apply(jQuery, array_of_ajax_requests_queue);`. The problem is that array_of_ajax_requests_queue has to be like that `[func1(), func2()]` – Dmitry Evseev Mar 15 '11 at 20:47
  • The issue I'm having isn't so much in the when() but more of how to start the queue and process it. – Graham Mar 15 '11 at 20:56