такие штуковины надо делать в параметризуемом виде.
вот, с обработкой ошибок
// запускатель асинхронной функции для параметров
/*
args: {
request: param => Promise
getKey: param => value
limit: number
params: array
}
return [...]
*/
function runRequests(args) {
if (!args.params) {
return Promise.resolve([]);
}
return new Promise(res => {
const results = new Array(args.params.length);
const map = new Map();
const req = []
for (let i = 0; i < args.params.length; ++i) {
const param = args.params[i];
const key = args.getKey ? args.getKey(param) : param;
let config = map.get(key);
if (!config) {
config = {
param: param,
indexes: [i]
};
map.set(key, config);
req.push(config);
} else {
config.indexes.push(i);
}
}
const limit = Math.min(args.limit || req.length, req.length);
let pos = 0;
let doneCount = 0;
function run() {
if (pos < req.length) {
const config = req[pos++];
args.request(config.param).then(
data => done(false, data, config),
error => done(true, error, config))
}
}
function done(error, value, config) {
// результат в комплексном виде, тут может быть как успешно, так и с ошибкой
const item = {
success: !error,
data: error ? undefined : value,
error: error ? value : undefined
};
for (let i = 0; i < config.indexes.length; ++i) {
results[config.indexes[i]] = item
}
doneCount++;
if (doneCount >= req.length) {
res(results);
} else {
run();
}
}
for (let i = 0; i < limit; ++i) {
run();
}
});
}
// пример асинхронной функции, которая получает параметр и возвращает промис
function asyncReverse(value) {
console.log('request ', value);
return new Promise((res, rej) => {
const r = Math.random();
const delay = Math.floor(2000 + 3000 * Math.random());
setTimeout(() => {
if (r < 0.00002) {
rej(r);
} else {
console.log('result for ', value);
res(value.split('').reverse().join(''));
}
}, delay);
});
}
// запуск для параметров
runRequests({
request: asyncReverse, // асинхронная функция
getKey: param => param, // ключ, по которому выявляем одинаковые параметры
limit: 3,
params: [
'1234',
'qazx',
'rwsxc',
'edcv',
'rfvb',
'edcv'
]
}).then(console.log)
смотреть в консоли результат можно