user70192
user70192

Reputation: 14204

JavaScript Arrays with Async Functions

I have an array of strings in JavaScript. The array is defined like the following:

var myArray = [];
myArray.push('1');
myArray.push('2');
myArray.push('3');

I need to loop through the array and call a function that runs asynchronously. That function looks like this:

function myAsyncFunction(id, callback) {
  $.ajax({
    url: '/api/items', 
    data: { 'id':id },
    type: 'POST',
    dataType: 'text',
    success: function(result) {
      if (callback) {
        callback();
      }
    }, error: function() {
      if (callback) {
        callback();
      }
    }
}

I'm trying to iterate through all of the items in my array and figure out how long it takes to run all of them. I want to do something like this:

var startTime = new Date();
for (var i=0; i<myArray.length; i++) {
  myAsyncFunction(myArray[i]);  
}
var duration = new Date() - startTime;

Obviously, the above does not work because it does not wait for the ajax call to finish before moving to the next item in the array. I know I need to use callbacks. However, I'm not sure how to structure my code that way. How do I do this?

Upvotes: 4

Views: 290

Answers (3)

user1839730
user1839730

Reputation:

Use Promise and do something like this:

var myArray = [1, 2, 3];
var promises = [];
var startTime = new Date();
var duration;

for (var i = 0, len = myArray.length; i < len; i++) {
    var def = $.Deferred();
    promises.push(def);

    (function(i) {
        $.ajax({
            url: '/api/items', 
            data: { 'id':myArray[i] },
            type: 'POST',
            dataType: 'text'
        }).done(function() {
            promises[i].resolve();
        });
    })(i);
}

$.when.apply($, promises).done(function() {
    duration = new Date() - startTime;
    console.log(duration);
});

I have not tested, but I think it can work well with some adaption :)
I think that the solution with the counter may fail under certain conditions.

EDIT: it works http://jsfiddle.net/0u21jwxv/

Upvotes: 2

Zee
Zee

Reputation: 8488

Try using a counter for this purpose. Once the counter value is 0 find the duration.

var startTime = new Date();
var counter = myArray.length; //COUNTER
for (var i=0; i<myArray.length; i++) {
  myAsyncFunction(myArray[i],function(){//Here you use the callback
   counter--;
   if(counter == 0){
     var duration = new Date() - startTime;
   } 
  });  
}

Upvotes: 1

AmmarCSE
AmmarCSE

Reputation: 30557

Keep track of how many calls you are going to make

var callCount = myArray.length;

Then, in the callbacks check if its the last one

success: function(result) {
      callCount--;
      if(callCount == 0){
          var duration = new Date() - startTime;
      }
}

Upvotes: 1

Related Questions