Elvis
Elvis

Reputation: 289

How to do Ajax requests with error handling and detect overall completition?

Some kinde of pseudo-synchronous question once again...

I'm looking for the best practice to run a function, after the completition of all ajax requests inside a loop.

Bad example:

var files = ["file1","file2","File3"];
var success = [];
var error = [];

for (var i = 0; i < files.length; i++) {
    $.ajax({
        type: "HEAD",
        url: files[i]
        }).done(function(){
            console.log("file found");
            success.push(files[i]);
            doThisWhenAllFilesChecked();
        }).fail(function () {
            console.log("file not found");
            error.push(files[i]);
            doThisWhenAllFilesChecked();
        })
}

Bad example 2: synchronous, just to illustrate what i'm looking for:

var files = ["file1","file2","File3"];
var success = [];
var error = [];

for (var i = 0; i < files.length; i++) {
    $.ajax({
        type: "HEAD",
        async: false, // <-- !
        url: files[i]
        }).done(function(){
            console.log("file found");
            success.push(files[i]);
        }).fail(function () {
            console.log("file not found");
            error.push(files[i]);
        })
}
doThisWhenAllFilesChecked();

Upvotes: 3

Views: 75

Answers (3)

atul
atul

Reputation: 562

Try something like this. Note this just pseudo code

var files = ["file1","file2","File3"];
var success = [];
var error = [];
var promisese = [];
function xhrCall(fileName){
   return $.ajax({
        type: "HEAD",        
        url: fileName
        });
}
function errorCallback(){
 // do something
}
for (var i = 0; i < files.length; i++) {
    promisese.push(xhrCall(files[i]));
}
$.when(promisese).then(doThisWhenAllFilesChecked, errorCallback);

Upvotes: 0

Gaurav Srivastava
Gaurav Srivastava

Reputation: 3232

you can do this-

 var files = ["file1","file2","File3"];
    var success = [];
    var error = [];
    var k = 0;
    for (var i = 0; i < files.length; i++) {
        $.ajax({
            type: "HEAD",
            url: files[i]
            }).done(function(){
                console.log("file found");
                 k++;
                success.push(files[i]);
                doThisWhenAllFilesChecked();
            }).fail(function () {
                 k++;
                console.log("file not found");
                error.push(files[i]);
               doThisWhenAllFilesChecked();
            })
    }

    function doThisWhenAllFilesChecked(){
      if(k==files.length){
        k = 0;
        //execute code here
      }
    }

Upvotes: 1

Liam
Liam

Reputation: 29694

You need to chain all the promises together, so something like:

var promiseArray = []
for (var i = 0; i < files.length; i++) {
    //ajax returns a promise so capture this.
     promiseArray.push($.ajax({
        type: "HEAD",
        url: files[i]
        }).done(function(){
            console.log("file found");
            success.push(files[i]);
        }).fail(function () {
            console.log("file not found");
            error.push(files[i]);
        })
   );
}

//when can accept an array of deffered objects just call then() after these all return
$.when(promiseArray).done(doThisWhenAllFilesChecked());

In the case where multiple Deferred objects are passed to jQuery.when(), the method returns the Promise from a new "master" Deferred object that tracks the aggregate state of all the Deferreds it has been passed. The method will resolve its master Deferred as soon as all the Deferreds resolve, or reject the master Deferred as soon as one of the Deferreds is rejected.

Note that doThisWhenAllFilesChecked() will run async also

Upvotes: 0

Related Questions