Задушить количество обещаний, открытых в данный момент

Следующий Typescript выполняет каждый вызовdoSomething(action) один за раз. (Это означает, что второй элемент в списке не получает вызов, пока не будет выполнен первый).

async performActionsOneAtATime() {
    for (let action of listOfActions) {
        const actionResult = await doSomethingOnServer(action);
        console.log(`Action Done: ${actionResult}`);
    }
 }

Этот отправит все запросы на сервер сразу (без ожидания каких-либо ответов):

async performActionsInParallel() {
    for (let action of listOfActions) {
        const actionResultPromise = doSomething(action);
        actionResultPromise.then((actionResult) => {
            console.log(`Action Done: ${actionResult}`);
        });
    }
}

Но что мне действительно нужно, так это способ их задушить. Может быть, 10 или 20 открытых звонков одновременно. (По одному слишком медленно, но все 600 будут перегружать сервер.)

Но мне трудно понять это.

Любые предложения о том, как я могу регулировать количество открытых вызовов X одновременно?

(Этот вопрос использует TypeScript, но я бы согласился с ответом ES6 JavaScript.)