I have code which is successfully running AJAX calls in sequence (a crude internet latency test for my employees):
const start = new Date().getTime();
const testUrl = "our server URL";
const start = new Date().getTime();
$.ajax(testUrl + '?delay=0.0&length=100').done(function(){
$.ajax(testUrl + '?delay=0.1&length=1000').done(function(){
$.ajax(testUrl + '?delay=0.2&length=10000').done(function(){
$.ajax(testUrl + '?delay=0.1&length=100000').done(function(){
$.ajax(testUrl + '?delay=0.2&length=10000').done(function(){
$.ajax(testUrl + '?delay=0.1&length=1000').done(function(){
$.ajax(testUrl + '?delay=0.0&length=100').done(function(){
$.ajax(testUrl + '?delay=0.1&length=10').done(function(){
const end = new Date().getTime();
internetTestTime = end - start;
console.log('Your internet test time: ' + internetTestTime + 'ms')
})
})
})
})
})
})
})
});
I would like to switch this to use Promises that run in sequence. Here is the progress so far:
const start = new Date().getTime();
const testSuiteInputs = [
{delay: 0.5, length: 100},
{delay: 0.4, length: 500},
// more tests here
];
let testSequence = Promise.resolve();
testSuiteInputs.forEach(testSuiteInput => {
// 🌟 something goes here...
});
testSequence.then(() => {
const end = new Date().getTime();
internetTestTime = end - start;
console.log('Your internet test time: ' + internetTestTime + 'ms')
});
What do I need to put at 🌟 above to make these Promises run sequentially?
Well, the simplest way would be to switch your .forEach()
loop to a plain for
loop inside an async
function and then use await
:
async function run() {
const start = new Date().getTime();
const testSuiteInputs = [
{delay: 0.5, length: 100},
{delay: 0.4, length: 500},
// more tests here
];
for (let item of testSuiteInputs) {
let url = `${testUrl}?delay=${item.delay}&length=${item.length}`;
let result = await $.ajax(url);
// process result here
}
}
run().then(finalResult => {
console.log("all done");
}).catch(err => {
console.log(err);
});
To do it without using async/await
, a common design pattern for sequencing asynchronous access to an array is to use .reduce()
where you just chain promises together:
const start = new Date().getTime();
const testSuiteInputs = [
{delay: 0.5, length: 100},
{delay: 0.4, length: 500},
// more tests here
];
testSuiteInputs.reduce((p, item) => {
return p.then(() => {
// when previous ajax call finished, start the next one
let url = `${testUrl}?delay=${item.delay}&length=${item.length}`;
return $.ajax(url).then(result => {
// process individual result here
});
});
}, Promise.resolve()).then(finalResult => {
console.log("all done");
}).catch(err => {
console.log(err);
});;