sorry if this question has been answered before but I couldn't find it.

I have an array of objects, and for each object I want to do an async call (ajax call), and when all async calls are finished, i want to call another function.

eg.

    var list = [Object, Object, Object, Object];
    var final= [];

    $(list).each(function(){
       //ajax call
       getSomething(data, function(data){
          final.push(data);
       });
    });

After all ajax calls are finished i wanna call function load(final);

Can this be done whith callbacks, and without libraries like when.js etc.

Th.

有帮助吗?

解决方案

Call the function when the last item has arrived:

final.push(data);
if (final.length == list.length) load(final);

其他提示

Since it looks like you have jQuery available, you can use the promises built into jQuery:

var list = [Object, Object, Object, Object];
var promises = [];

$.each(list, function(){
   //ajax call
   promises.push($.get(data));
});
$.when.apply($, promises).done(function() {
    // all ajax calls done
    // data from each ajax call is in arguments[0], arguments[1], etc...
    load(arguments);
});

One other nice advantage of this mechansim vs. all the others shown so far is that this will keep the results in the order that you requested them, even if they don't come back in that order.

You can also provide a handler to .fail() in addition to .done() (or specify both with a .then(f1, f2)) if you want to catch the case where any ajax call fails.

This is a way to solve the problem with a simple counter

var counter = $(list).length;
$(list).each(function(){
   $.get('URL', function(data){
        /* do whatever you need for each list item */
        if(--counter === 0){
            /* Do whatever you wanted to do when all requests completed */
        }
   });
});

Fundamentally, you keep track of how many calls you've made and how many responses you've gotten, and when you've got all the responses, you call load(final). In your case, quite conveniently you have two arrays and are pushing the results of the calls based on the first array into the second, so you can compare their lengths. (Of course, you'll want to handle the error condition as well.)

Your quoted code is a bit suspect (I think you wanted $.each(list, ..., not $(list).each(...), but I think you probably meant something like this:

var list = [Object, Object, Object, Object];
var final= [];

$.each(list, function(data){
   //ajax call
   getSomething(data, function(result){ // <= I used `result` rather than `data`; using the same symbol in intermixed code like this is asking for trouble
      final.push(result);
      if (final.length === list.length) {
          // All done
          load(final);
      }
   });
});
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top