Redrif Redrif - 15 days ago 6
Ajax Question

AJAX continue/resume after abort

Hello guys,

i would like to ask if there is any possibility to continue aborted ajax. I got arraz of ajax calls in defferreds like this:

var defferreds = [];
defferreds.push(
$soap.ajax({
type: "POST",
dataType: "json",
url: "some_url.php",
cache: false,
}).done(function(data) {
/* do something */
}).fail(function(jqXHR,status, errorThrown) {
console.log(jqXHR.responseText);
})
);


There are like 20 more ajax(es) in the defferreds array. When user clicks on abort_ajax button, it should abort all ajaxes that are not done yet. I use this function to do so:

function abort_ajaxes(){
for(var i = 0; i < defferreds.length; i++){
if(defferreds[i] && defferreds[i].readyState != 4){
defferreds[i].abort();
} else {
delete defferreds[i];
}
}
}


Here goes the part where i need your help. As soon as user clicks on resume_ajax button, it should call the remaining ajaxes out of the defferreds array and complete them. The problem is, that i dont have a clue how to start aborted ajax even though i have it stored in my array of defferreds. Is it possible to resume aborted ajaxes? And only those which were aborted and not the ones that have succesfuly ended?

EDIT:
Im asking if there is possibility to rerun only not completed ajaxes. I tried the solution that is used in here, but it does not solve my concrete problem. Once i click on resume_ajax button nothing happens even though i used this code :

$('.resume_ajax').click(function(){
for (var key in defferreds){
$soap.ajax(defferreds[key]);
}
});


What is the exact line of code that calls aborted ajaxes again? Can it even be achieved with ajax call looking like one in my defferreds array? Because as i said, nothing happened.

EDIT2:

I run the ajaxes like this:

function run_ajaxes(){
var defferreds = [];
/* there are around 20 same ajax calls just with another url */
defferreds.push(
$soap.ajax({
type: "POST",
dataType: "json",
url: "some_url.php",
cache: false,
}).done(function(data) {
/* do something */
}).fail(function(jqXHR,status, errorThrown) {
console.log(jqXHR.responseText);
})
);
}

$('.run_ajaxes').click(function(){
run_ajaxes();
});

Answer

I made a very simple solution for you. Here I have one outpu div for progress reporting, and two buttons, abort which when it is clicked will abort all still running requests, and continue button, which will resume the execution of aborted requests.

To test the solution, press the continue button first. I used https://httpbin.org/delay mockup server for mocking the requests. Than press abort button while there are still some running requests. And than press continue button again - this will start the execution of all undone requests.Here is the code

var output = $("#output");
var ajaxes = [];
var count = 10;

// Function which will run the ajax call
function run(idx) {
  // Get the ajax args
  var args = $.extend({}, ajaxes[idx]);
  
  // Run the ajax and replace the args with ajax deferred
  ajaxes[idx] = $.ajax(args)
    .done(function() {
  	  $(output.find("p")[idx]).html("done");
    })
    .fail(function() {
  	  $(output.find("p")[idx]).html("aborted");
      // Replace the ajax deferred with the original ajax args
      ajaxes[idx] = args;
    });
}

for(var i = 0; i < count; i++) {
  // Create output element to report progress for each ajax call
  output.append("<p>sleeping</p>");
  
  // Custom delayed response 
  var delay = Math.floor((Math.random() * 5) + 1);
  
  // Create ajax arguments
  var args = {
    type: "GET",
    dataType: "json",
    url: "https://httpbin.org/delay/" + delay
  };
  
  // Store the ajax args
  ajaxes[i] = args;
}

$("#abort").on("click", function() {
  for(var i = 0; i < count; i++) {
  	// Abort each undone ajax call
    if(ajaxes[i].readyState != 4) {
      ajaxes[i].abort();
    }
  }
});

$("#continue").on("click", function() {
  for(var i = 0; i < count; i++) {
  	// Run all ajax call that where not finished yet
    if(!ajaxes[i].readyState) {
    	$(output.find("p")[i]).html("... loading");
      run(i);
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="continue">continue</button>
<button id="abort">abort</button>
<div id="output"></div>