Я предполагаю, что это то, чего вы пытаетесь достичь:
function printFunc(output) {
// Replaced with console.log for my own convenience
console.log(output);
}
// Not really a factory, just a curry of the outputFunc
function loggerFactory(outputFunc) {
return function startLogger(name, interval) {
// Variables to keep track of the iterations and a reference to the interval to cancel
let logCount = 0;
let intervalRef;
function tick() {
// On each tick, check if we're done
// If yes, clear the interval and do the last output
// If no, do some output and increment the iterator
// Once the next tick passes we'll check again
// If you were using setTimeout instead you would have to requeue the tick here
if (logCount >= 10) {
clearInterval(intervalRef);
outputFunc('Done ' + name);
} else {
outputFunc(logCount + " " + name);
logCount += 1;
}
}
// Start it of
intervalRef = setInterval(tick, interval);
}
}
const logger = loggerFactory(printFunc);
function startMeUp() {
console.log('Starting');
logger('Log1', 1000);
logger('Log2', 1200);
logger('Log3', 1700);
}
startMeUp();
Некоторые примечания: Вы можете поместить в поле intervalRefs массив, но я считаю, что лучше инкапсулировать эту работу в одном и том же логгере. , поскольку он все равно должен очищаться сам по себе.
При работе с интервалами (или асинхронным кодом в целом) для циклов обычно не то, что вы ищете. Поскольку циклы по своей сути синхронны, все итерации будут выполняться непосредственно друг за другом, без места для чего-либо еще. То, что вы искали, это способ запуска нескольких асинхронных «треков» одновременно. Вы можете использовать цикл for для запуска этих «треков», таких как:
for () {
logger('Log' + i, 1000 * i);
}
Но ключ заключается в том, что регистратор быстро устанавливает функцию интервала и затем возвращает. Таким образом, ваш цикл for может быстро «планировать» задачи, но регистратор выполняет внутренние итерации асинхронно, используя setInterval или setTimeout.