Primero de todo, declarar let b = true
fuera de la función de devolución de llamada. Es re-inicializado en cada llamada de otra manera.
En segundo lugar, el 10000 en clearTimeout(fnInterval, 10000)
no es un parámetro válido. clearTimeout(timeoutId)
acepta sólo el primer parámetro y borra el tiempo de espera pasó inmediatamente. Necesitarías setTimeout
para activar esto después de 10 segundos, si ese es tu objetivo. Pero que causa una condición de carrera entre los dos tiempos de espera -- imprecisión puede significar que vas a perder algunos de los registros de viento o con extra de registros.
El uso de un contador es una solución, como otras respuestas muestran, pero generalmente cuando estoy utilizando complejos de tiempo con setInterval
que requiere de compensación después de un cierto número de iteraciones, yo refactorizar a un genérico promisified sleep
función que se basa en setTimeout
. Esto mantiene el llamado código mucho más limpio (no las devoluciones de llamada) y evita jugar con clearTimeout
.
En lugar de un valor booleano para voltear una bandera de ida y vuelta entre dos mensajes, la mejor solución es utilizar una matriz y el módulo, el índice actual de los mensajes de la matriz de longitud. Esto hace que sea mucho más fácil para agregar más elementos a recorrer y el código es más fácil de entender ya que el estado está implícita en el mostrador.
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);
}
})();