Обычная очередь. Что-то типа такого:
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
class AsyncQueue {
queue = [];
interval = 100;
asyncFunction = fetch;
constructor(options) {
Object.assign(this, options);
this.execute.bind(this);
}
execute(...args) {
let params;
const promise = new Promise((resolve, reject) => params = {
args,
resolve,
reject
});
this.queue.push(params);
if(this.queue.length === 1)
this.stream();
return promise;
}
async stream() {
for (const { args, resolve, reject } of this.queue) {
await this.asyncFunction(...args).then(resolve, reject);
await delay(this.interval);
}
this.queue.length = 0;
}
}
const queue = new AsyncQueue({
asyncFunction(...fetchOptions) {
return fetch(...fetchOptions).then(response => {
if(!response.ok) throw new Error(response.status);
return response.text();
})
}
});
queue.execute('/1').then(console.log, console.warn)
queue.execute('/2').then(console.log, console.warn)
queue.execute('/3').then(console.log, console.warn)
asyncFunction - тут fetch, но может быть любой возращающей Promise в том числе на основе XMLHttpRequest.
Можно то же самое и без class, Promise и await написать, на колбэках, но мне лениво.)