问题
I have an ajax request that grabs some data and then splits it up into an array. The array length is variable.
var ajax1 = $.ajax({
url: 'myurl.php',
type: "GET",
dataType: "jsonp",
success: function (data) {
//create an array
}
});
Once I have the array, I want to loop through it and in each iteration run another AJAX request. I put it inside a $.when to make sure the initial ajax request was complete:
$.when(ajax1).done(
function() {
for (i = 0; i < array.length; ++i) {
$.ajax({
url: 'anotherurl?=' + myarray[i],
type: "GET",
dataType: "jsonp",
success: function (data) {
//do stuff here
}
});
}
}
)
My question is, how can I get a message box to pop up when the for loop has completed all the AJAX requests? A simple alert('complete')
at the end of the loop won't work as the AJAX is done async.
回答1:
You can achieve this by also using $.when
. You just need to store all the AJAX requests you make in an array and apply()
that array to $.when
. Try this:
$.when(ajax1).done(function() {
var requests = [];
for (i = 0; i < array.length; ++i) {
requests.push($.ajax({
url: 'anotherurl?=' + myarray[i],
dataType: "JSONP",
success: function (data) {
// do stuff here
}
}));
}
$.when.apply($, requests).done(function() {
console.log('complete');
});
})
You can also shorten the logic slightly by using map()
, although be aware this won't work in < IE9.
$.when(ajax1).done(function() {
var requests = array.map(function() {
return $.ajax({
url: 'anotherurl?=' + myarray[i],
dataType: "JSONP",
success: function (data) {
// do stuff here
}
});
});
$.when.apply($, requests).done(function() {
console.log('complete');
});
})
回答2:
As of JQuery 1.5, $.ajax()
return an object which implement the promise interface, so you can store all of those promises in an array and wait for them to finish using Promise.all()
.
Something like:
var root = 'http://jsonplaceholder.typicode.com';
var p = [];
p.push( $.ajax({url: root + '/posts/1', method: 'GET'}));
p.push( $.ajax({url: root + '/posts/2', method: 'GET'}));
p.push( $.ajax({url: root + '/posts/3', method: 'GET'}));
p.push( $.ajax({url: root + '/posts/4', method: 'GET'}));
Promise.all(p).then(values => {
console.log( 'Ajax responses after they have all finished: ', values);
});
See this plnkr for an exemple.
Hope this help !
回答3:
jQuery is going to rear its stubborn head pretty quickly here. I'd recommend you reach for something better like Promises that give you more control in this type of situation
const pajax = opts=>
new Promise((resolve, reject)=>
$.ajax(opts).done(x => resolve(x)).fail((_,_,err)=> reject(err))
Then you could use it like this with Promise.all
pajax({
url: 'myurl.php',
type: "GET",
dataType: "jsonp",
})
.then(data => {
// create your arr
let arr = ...
return Promise.all(arr.map(x=> {
return pajax({
url: 'anotherurl?=' + x,
type: "GET",
dataType: "jsonp"
})
}))
})
.then(data => {
console.log('this is called after all promises are done'
})
.catch(err=> {
console.error(err)
})
EDIT
@RoryMcCrossan's answer is nice if you want to keep everything in the jQuery realm
来源:https://stackoverflow.com/questions/38738614/when-all-ajax-requests-complete