Современным подходом является await в цикле, но ничего не мешает сделать рекурсивную функцию, как во времена колбэков:
function loop(array, getPromise) {
array = array.slice();
const responses = [];
return new Promise(function innerLoop(resolve, reject) {
if (array.length) {
return getPromise(array.shift()).then(response => {
responses.push(response);
innerLoop(resolve, reject);
}, reject);
}
resolve(responses);
});
}
function request(url) {
return new Promise((res, rej) => {
const delayTime = Math.floor(Math.random() * 10000) + 1;
setTimeout(() => res(url), delayTime);
});
}
loop(['a', 'b'], request).then(console.log, console.error);