Ваш код не работает, потому что lsCommand()
неблокирующий, асинхронный. Все, что он делает, это запускает операции вызова и затем сразу же возвращается. Итак, ваш цикл for
начинает работать, затем ваши циклы while
запускаются на первой итерации цикла for
и запускают вызовы max lsCommand()
, а затем завершаются. Последующим итерациям цикла for
больше нечего делать, поскольку вызовы max
lsCommand()
уже выполняются. Итак, поскольку lsCommand()
не является блокирующим, ваш цикл for
завершается, и все, что он делал, это запускал max
lsCommand()
операции и затем ваш цикл завершался. Что вам нужно сделать, так это следить за завершением каждого lsCommand() by monitoring
ls.on ('close') `, а затем, когда каждый из них завершится, вы сможете запустить другой. Вы можете увидеть, как я это делаю, в моем коде ниже.
Вы можете сделать что-то вроде этого, когда вы создадите внутреннюю функцию с циклом для запуска процессов до вашего предела, а затем просто продолжаете вызывать эту функцию каждый раз, когда завершается операция вызова (которая каждый раз запускается еще одна). заканчивается):
function listDirs(dirsToVisit, maxAtOnce) {
let numRunning = 0;
let index = 0;
function runMore() {
// while we need to start more, start more of them
while (numRunning < maxAtOnce && index < dirsToVisit.length) {
++numRunning;
const ls = spawn("ls", [dirsToVisit[index++]]);
ls.on("close", code => {
--numRunning;
console.log(`Finished with code ${code}`);
runMore();
}).on("error", err => {
--numRunning;
runMore();
});
}
if (numRunning === 0) {
// all done with all requests here
}
}
runMore();
}
Для некоторых более общих реализаций, смотрите эти:
Цикл запроса API с переменным URL
Promise.all потребляет всю мою оперативную память
Javascript - как контролировать количество обещаний доступа к сети параллельно
Nodejs: асинхронный запрос со списком URL