I want to make a series of ajax requests to a server and then do a final ajax request that uses data I received previously. Obviously, I need to wait for the earlier requests to finish before doing the final request. I'm having trouble implement this in javascript.
I don't want to overwhelm the server, so ideally all requests would be done sequentially.
My simple test code is as follows (replacing web requests with a sleep):
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
var urls = ['1', '2', '3'];
const slowFunc = () => {
urls.forEach(async (url) => {
//Don't change this section!
console.log("a"+url);
await sleep(5000);
console.log("b"+url); //I want this to run before c
});
};
slowFunc();
console.log("c");
This prints "c" before by sleep is finished, which is wrong. How can I get the output to be as follows?
a1
b1
a2
b2
a3
b3
c
Out of interest, how would I get this output? (The exact ordering within the a and b section is unimportant.)
a1
a2
a3
b1
b2
b3
c
I tried reading ES2018: asynchronous iteration but it blew my mind.
Update: I quickly had second thoughts about my example, so here is a better one (that still doesn't work):
var urls = ['https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.2.0/purify.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.8.3/system.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/slim-select/1.18.6/slimselect.min.js'];
var results = {};
const webRequest = (url) => {
$.ajax({
type: "GET",
url: url,
}).then(data => {
results[url] = data;
console.log("b"+url+","+results[url]); //I want this to run before c
});
}
const slowFunc = () => {
urls.forEach((url) => {
console.log("a"+url);
webRequest(url);
});
};
slowFunc();
console.log("c");
Thanks for comments so far.
Update 2: Solution to the web request problem, based on Antonio Della Fortuna's advice:
var urls = ['https://cdnjs.cloudflare.com/ajax/libs/dompurify/2.2.0/purify.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/systemjs/6.8.3/system.min.js', 'https://cdnjs.cloudflare.com/ajax/libs/slim-select/1.18.6/slimselect.min.js'];
var results = {};
const webRequest = (url) => {
return new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: url,
error: function (data, status, er) {
console.log("b,"+url+",failed");
resolve();
},
}).then(data => {
results[url] = data;
console.log("b,"+url+","+results[url]); //I want this to run before c
resolve();
});
});
}
const slowFunc = async () => {
for (let i = 0; i < urls.length; i++)
{
var url = urls[i];
console.log("a,"+url);
await webRequest(url);
};
};
slowFunc().then(() => {
console.log("c");
console.log(results);
})