Peter Rader Peter Rader - 7 months ago 17
Javascript Question

Deferred and Ajax

Reading a JSON-Service like this:

$.ajax({
url:'activeIDs',
success : function(data){ // data = [14,15]
var tableRows = [];
for (var dataIndex=0; dataIndex < data.length; dataIndex++) {
var isLast = dataIndex == data.length;
$.ajax({
url: 'info?id=' + data[dataIndex],
success: function(data2) { // "foo", "bar"
tableRows.push(data2.name);
if (isLast) {
alert(tableRows.length);
}
}
});
}
}
});


First network-trace is:


  1. activeIDs =
    [14,15]

  2. info?id=14 (takes 2 seconds) =
    "foo"

  3. info?id=15 (takes 4 seconds) =
    "bar"



In this case the alert gives "2".

Seconds network-trace is different:


  1. activeIDs =
    [14,15]
    ;

  2. info?id=14 (takes 20 seconds) =
    "foo"
    (now takes very long)

  3. info?id=15 (takes 1 second) =
    "bar"



In this case the alert gives
1
after one second, this is bad!!!

Question:



How to use $.Deferred instead of
isLast
?

Answer

You'll need to wait for all requests to finish before alerting.

$.ajax({
  url:'activeIDs',
  success : function(data){ // data = [14,15]
    var tableRows = [];
    var requests = [];
    for (var dataIndex=0; dataIndex < data.length; dataIndex++) {
      var isLast = dataIndex == data.length;

      var request = $.ajax({
        url: 'info?id=' + data[dataIndex],
        success: function(data2) { // "foo", "bar"
          tableRows.push(data2.name);
        }
      });

      requests.push(request);
    }

    // wait for all requests to finish here
    $.when(requests).then(function(){
      // all success functions have been called and updated things appropriately
      alert(tableRows.length);
    }
  }
});

This assumes that all requests succeed. It also looks like there are a few typos

  • Where does tableRows get updated?
  • Where is entries defined?
Comments