Обещания «выполняются», как только они появляются, поэтому, когда у вас есть их массив, вы не можете ожидать, что некоторые из них будут задержаны.
Однако вы могли бы работать смассив функций , которые - при вызове - вернут новое обещание.Параметр max
будет определять, сколько из этих функций вы на самом деле будете вызывать немедленно, а остальные функции будут вызываться только тогда, когда «комната» станет доступной после разрешения одного из обещаний.
Вот как вы могли бы это сделатьсделать это:
// Main function.
// Parameters:
// - the maximum number of unresolved promises that may exist at a given time
// - an array of promise-creating functions
function throttle(maxPending, asyncFuncs) {
return new Promise((resolve, reject) => {
let numPending = 0;
let nextFuncId = 0;
const promisedValues = [];
(function check() {
if (nextFuncId >= asyncFuncs.length) { // All promises created
if (numPending == 0) resolve(promisedValues); // All promises fulfilled
return;
}
while (numPending < maxPending) { // Room for creating promise(s)
numPending++;
const thisFuncId = nextFuncId++;
asyncFuncs[thisFuncId]().then(value => {
promisedValues[thisFuncId] = value;
numPending--;
check();
}).catch(reject);
}
})();
});
}
// Demo:
// The usual delay function: returns a promise that resolves after given delay
const delay = (ms) => {
console.log("Start delay of " + ms + "ms");
return new Promise(resolve => setTimeout(resolve, ms))
.then(() => console.log("End delay of " + ms + "ms"));
};
// Curry for the above: pass the milliseconds and return a function
// that can create a promise for it
const delayF = (ms) => delay.bind(null, ms);
// Pass 5 promise-creating functions, but only allow 3 concurrently pending promises:
throttle(3, [delayF(1000), delayF(500), delayF(800), delayF(300), delayF(900)])
.then(() => console.log("all done"));