IMHO there are some inaccuracies in your code. First of all, when you call $.when.apply()
, between .when()
parenthesis, you have to put "$
" as first arguments, then your array spRequest
. If you work with jQuery.Deferred
you can control better the final result of your Deferreds (ajax calls and so on...).
So, you push in spRequest
array your Deferreds, that are executed ASAP. $.when.apply($,spRequest)
waits for all Deferreds to be resolved or rejected.
I deliberately put self.resolve()
in every ajax.fail()
instead of self.reject()
because of two reasons:
- you want to count your ajax fails;
if in a series of Deferred objects one of them fails, $.when.fail()
fires and I think is not what you're searching for, or, better, I suppose that the files called by your ajax calls exist and can be correctly called. On the other hand, if it is not so, you have two possibilities:
- use
self.reject()
on ajax.fail()
;
- consider to check statusCode in your ajax call:
$.ajax({
statusCode: {
404: function() {
//resolve and counter ++ stuffs in here
}
}
});
Here it is an example that goals your needs:
* index.php *
<html>
<head>
<title>TEST DEFERRED</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
</head>
<body>
<h1>TEST DEFERRED</h1>
<script src="js/test.js"></script>
</body>
</html>
* test.js *
var counter = { ok:0, fail:0 }
,toDoList = [1,2,3,4,5,6,7,8,9,10]
,spRequest = [];
for(var i in toDoList)
{
console.log(i, i&1);
if(i&1)
{
console.log('odd, request an ok ajax call');
spRequest[i] = jQuery.Deferred(function(){
console.log('function ok called!');
var self = this;
$.ajax({
url: 'ajax/ajax_return_ok.php',
async: true,
data : {},
type: 'post',
dataType: 'json'
}).done( function(d) {
console.log(d);
if(d.is_error)
{
counter.fail ++;
self.resolve();
} else {
counter.ok ++;
self.resolve();
}
}).fail( function(j) {
console.log(j.responseText);
//# fail of ajax call
counter.fail ++;
self.resolve();
});
});
} else {
console.log('odd, request an error ajax call');
spRequest[i] = jQuery.Deferred(function(){
console.log('function error called!');
var self = this;
$.ajax({
url: 'ajax/ajax_return_error.php',
async: true,
data : {},
type: 'post',
dataType: 'json'
}).done( function(d) {
console.log(d);
if(d.is_error)
{
counter.fail ++;
self.resolve();
} else {
counter.ok ++;
self.resolve();
}
}).fail( function(j) {
console.log(j.responseText);
//# fail of ajax call
counter.fail ++;
self.resolve();
});
});
}
}
jQuery.when.apply($,spRequest).done(function(){
console.log('when done');
}).fail(function(){
console.log('when fail');
}).always(function(){
if ( counter.fail === 0 )
{
console.log( "everything went just fine" );
}
else
{
console.log( "there were some problems:" );
console.log( "- Requests OK: " + counter.ok );
console.log( "- Requests failed: " + counter.fail );
}
});
* ajax_return_error.php *
<?php
echo json_encode(array('is_error' => true,'error_message' => 'this is an error message'));
* ajax_return_ok.php *
<?php
echo json_encode(array('is_error' => false,'result' => 'ok'));
Apologize in advance for not having create a Fiddle.
Hope my answer helps.