Прежде всего, объявите let b = true
вне функции обратного вызова. В противном случае он повторно инициализируется при каждом вызове.
Во - вторых, 10000 в clearTimeout(fnInterval, 10000)
не является допустимым параметром. clearTimeout(timeoutId)
принимает только первый параметр и немедленно удаляет время ожидания, переданное. Вам понадобится setTimeout
чтобы запустить это через 10 секунд, если это ваша цель. Но это вызывает состояние гонки между двумя тайм-аутами-неточность может означать, что вы пропустите некоторые журналы или получите дополнительные журналы.
Использование счетчика-это одно из решений, как показывают другие ответы, но обычно, когда я использую сложное время с setInterval
для этого требуется очистить его после некоторого количества итераций, я рефакторирую до общего обещанного sleep
функция, основанная на setTimeout
. Это делает вызывающий код намного чище (без обратных вызовов) и позволяет избежать возни с clearTimeout
.
Вместо логического значения для переключения флага туда и обратно между двумя сообщениями лучшим решением является использование массива и модуль текущего индекса по длине массива сообщений. Это значительно облегчает добавление большего количества элементов для циклического просмотра, а код легче понять, поскольку состояние неявно указано в счетчике.
const sleep = ms => new Promise(res => setInterval(res, ms));
(async () => {
const messages = ["hi", "bye"];
for (let i = 0; i < 10; i++) {
console.log(messages[i%messages.length]);
await sleep(1000);
}
})();