How To Make A Foreach Loop Wait For Each Ajax Function To Finish
I have an array of statements and I want to loop through each and submit to the server via an ajax call. I have to make sure each ajax request is executed before the next request i
Solution 1:
use promises :
var promises = [];
for (var i = 0; i < $total_files; i++) {
// jQuery returns a prom
promises.push($.ajax({
/* your ajax config*/
}))
}
Promise.all(promises)
.then(responseList => {
console.dir(responseList)
})
Solution 2:
you could use this solution by using await
, for example :
for (let f of files) {
await $.ajax({/* your ajax config*/ });
}
Solution 3:
I wrote this function, PromiseAllSeq, to execute an array of promises sequentially.
You can pass a callback as the second parameter if you choose, but given your issue i've put together a working demo based on your code.
console.clear();
/**
* Promises will wait for each other and will return any[].
* If a promise is rejected it will stop.
* @paramarr - (Promise<any> | ()=>Promise<any>)[] - Accepts promise or a function that returns a promise
* @param callback(response, index) - If callback 'returns' it will overwrite the current response. Useful for changing the response.
* @returns any[]
*/constPromiseAllSeq = (arr, callback) => {
let result = [];
if (typeof callback !== 'function') {
callback = () => {};
}
constrec = (arr) => {
returnnewPromise((resolve, reject) => {
if (arr.length) {
(typeof arr[0] === 'function' ? arr[0]() : arr[0]).then(res => {
let cb = callback(res, result.length);
result = result.concat(typeof cb !== 'undefined' ? cb : res);
arr.splice(0, 1);
resolve(arr.length ? rec(arr) : result);
}).catch(err => {
reject(err);
})
} else {
resolve(result);
}
})
}
returnrec(arr);
}
functionsuccesHandler(data, index) {
// Here i can alter 'data'
data['finishedPromiseNr'] = index;
console.log("promise test ", data, index);
console.log("Go for next ");
return data;
}
functionerrorHandler(err) {
console.log("Error occurred ", err);
}
functionsubmitAjaxData(form, datafield) {
console.log("called submitAjaxData ", datafield);
//var loadurl = domainName + "/ajax-call-handler";// Mock some requests with delayed responses// https://reqres.in/#consolevar loadurl = "https://reqres.in/api/users?delay=" + datafield.fakeDelay;
return $.ajax({
url: loadurl,
method: "GET",
data: datafield
});
}
functionformPostSubmission(form) {
var parts = ['a', 'b', 'c'];
var i = 0;
let poll = [];
parts.forEach(function(entry) {
i++;
// 'datafield' was not assigned with var or let// Reassigning it on each loop will allow 'datafield' to pass in the anonymous function belowlet datafield = {
answer: entry,
displayOrder: i,
ajaxName: 'statementPartialSubmit',
fakeDelay: parts.length - i
};
// Wrong: submitAjaxData is called, that means, the requests are sent immediately.// poll.push( $.when(submitAjaxData(form, datafield) );// Correct: Wrap and return $.when into a function otherwise 'submitAjaxData' will trigger the requests
poll.push(() => $.when(submitAjaxData(form, datafield)));
});
PromiseAllSeq(poll, succesHandler).then(responseList => {
console.log('final response');
console.log(responseList);
}).catch(errorHandler)
}
formPostSubmission(null);
<scriptsrc="https://code.jquery.com/jquery-3.3.1.min.js"></script>
Solution 4:
async: false
is the best option in your case
Post a Comment for "How To Make A Foreach Loop Wait For Each Ajax Function To Finish"