Deferred and Ajax

不羁岁月 提交于 2019-12-09 05:44:58

问题


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 - 1);
      $.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?


回答1:


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]
      }).done(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?

Edit Now using promise style success handler. Should push the result in to tableRows before calling the $.when().then callback




回答2:


Why do you want $.Deferred ? Your $.ajax calls are returning a promise, so, you can use it:

var promisesArray = [];
for (var dataIndex=0; dataIndex < data.length; dataIndex++) {
  promisesArray.push($.ajax({...}));
}
 $.when.apply($, promisesArray).then(...);

(inspired by this answer)

You can use deferreds by taking this solution and passing it to a deferred if you want, but it's not neccesary:

var x = $.Deferred(function(defer){  
    var promisesArray = [];
    for (var dataIndex=0; dataIndex < data.length; dataIndex++) {
      promisesArray.push($.ajax({...}));
    }
     $.when.apply($, promisesArray).done(function(data) { defer.resolve(data); });
});
return x.promise();

(Not tested, I'm sorry)




回答3:


Use jQuery when

// Function to return id info based on this example http://stackoverflow.com/questions/5316697/jquery-return-data-after-ajax-call-success 
function getInfo(ID) {
return $.get("info?id=" + ID);  
}
// based on examples from https://api.jquery.com/jQuery.when/
var promises = [];
var jqxhr = $.get("activeIDs")
  .done(function(data) {
    $.each(data,function(i,v) {
        promises.push(getInfo(v));
    });
    $.when(promises).done(function(p) {
        console.log(p,p.length);
    });
  })
  .fail(function() {
    alert( "Error" );
  });


来源:https://stackoverflow.com/questions/37047280/deferred-and-ajax

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!