简体   繁体   中英

multiple simultaneous ajax requests broker

How to coordinate simultaneous ajax calls and take action only when all of them are completed?

Is there a convenient javascript helper library that will coordinate multiple simultaneous ajax calls to a database and invoke a specified callback when ALL of the ajax data-fetches have returned their data? I'd like to submit a dictionary of primed-and-ready-to-go ajax calls to this "coordinator" or "broker", along with my WhenAllCompleted callback function.

The use case is a common one: before a database record can be bound to the UI, all of the dropdown lists for the foreign key data relationships have to be populated, so that the user sees meaningful values rather than the integer keys that are typically stored in the record.

I would rather not reinvent all the plumbing code to track the status of each ajax request if there's a robust standard library out there for doing it already.

EDIT: Here's the pseudo-code that describes what I want to do :

           when ajax1fetch is finished
           and
           ajax2fetch is finished
           and 
           ajax3fetch is finished
           and SELECT1 is populated
           and SELECT2 is populated
           and SELECT3 is populated
           bindRecordToUI()

Before I restructured the code to use $.when() , I was getting the data in the .ajax() success callback, and populating the SELECT right there in that callback; when the SELECT was populated, then I bind the record to the UI.

If we feed $.when a list of ajax calls, the done callback is invoked when the ajax requests are complete, which occurs before the SELECTs are populated (if the list of items for the SELECT is very long).

Somehow I need to include the population of the SELECT elements as additional when-conditions, and find a way to route the data returned by the ajax call to the populating functions, if the SELECT-populate functions are not going to be peformed in the .ajax success callback.

You are looking for promises in JS. Here is a nice framework Q . And the allSettled() function is, what you are looking for.

Q.allSettled([saveToDisk(), saveToCloud()]).spread(function (disk, cloud) {
    console.log("saved to disk:", disk.state === "fulfilled");
    console.log("saved to cloud:", cloud.state === "fulfilled");
}).done();

Code taken from the API-reference

Since you are already using jQuery, you can use the jQuery.when() method to wait for multiple Deferred s to finish. Note that jQuery.ajax() (and its wrapper methods, like jQuery.get() ) returns a jqXHR object that is a type of Deferred .

You'll get your Deferred s from your $.ajax or equivalent calls, and then pass those all to $.when . You will get back a Promise , which is basically a read-only Deferred *. You can then attach completion/error handlers to this Promise , which will be resolved once all of your passed-in Deferred s are resolved, or is rejected if any one of your Deferred s is rejected.

var def1 = $.ajax(),
    def2 = $.ajax({ /* some params */});

var masterPromise = $.when(def1, def2);

masterPromise.done(function() {
    console.log('def1 and def2 are done!');
});

  • A Deferred allows attaching various done and error handlers, as well as resolving and canceling and otherwise controlling the asynchronous action. A Promise only allows the attachment of handlers, and does not allow control over the asynchronous action. You can get a Promise from a jQuery Deferred with the Deferred.promise() method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM