Así es como se ve mi código:
var fnInterval = setInterval(function() { let b = true if (b) { console.log("hi") } else { console.log("bye") } b = !b }, 1000); clearTimeout(fnInterval, 10000)Soy un novato en JavaScript y mi objetivo aquí es registrar en la consola un mensaje cada 1 segundo por una duración total de 10 segundos, pero durante cada intervalo quiero que mi mensaje alterne su valor entre "hola" y "adiós". ¿Cómo puedo hacerlo? (a partir de ahora, muestra el valor del booleano predeterminado y no cambia más adelante)
Mueva la variable de bandera fuera de la función:
let b = true; const fnInterval = setInterval(function() { if (b) { console.log("hi"); } else { console.log("bye"); } b = !b }, 1000); Para detener el temporizador después de 10000 milisegundos, ajuste la llamada a clearInterval en un setTimeout :
setTimeout(() => clearInterval(fnInterval), 10000); Mientras tanto, tenga en cuenta que el valor de retorno de setInterval no es una función sino un número, por lo que puede ser engañoso llamarlo fnInterval .
En primer lugar, declare let b = true fuera de la función de devolución de llamada. De lo contrario, se reinicializará en cada llamada.
En segundo lugar, el 10000 en clearTimeout(fnInterval, 10000) no es un parámetro válido. clearTimeout(timeoutId) acepta solo el primer parámetro y borra el tiempo de espera pasado inmediatamente. Necesitaría un setTimeout para activar esto después de 10 segundos, si ese es su objetivo. Pero eso provoca una condición de carrera entre los dos tiempos de espera: la imprecisión puede significar que perderá algunos de los registros o terminará con registros adicionales.
Usar un contador es una solución, como muestran otras respuestas, pero generalmente cuando estoy usando un tiempo complejo con setInterval que requiere borrarlo después de algunas iteraciones, refactorizo a una función de sleep prometida genérica basada en setTimeout . Esto mantiene el código de llamada mucho más limpio (sin devoluciones de llamada) y evita jugar con clearTimeout .
En lugar de un booleano para alternar una bandera entre dos mensajes, una mejor solución es usar una matriz y modular el índice actual por la longitud de la matriz de mensajes. Esto hace que sea mucho más fácil agregar más elementos para recorrer y el código es más fácil de entender ya que el estado está implícito en el contador.
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); } })();setInterval() es detenido por clearInterval() no por clearTimeout() . Los detalles se comentan en el código a continuación.
// Define a counter let i = 0; // Define interval function const fnCount = setInterval(fnSwitch, 1000); function fnSwitch() { // Increment counter i++; // if counter / 2 is 0 log 'HI' if (i % 2 === 0) { console.log(i + ' HI'); // Otherwise log 'BYE' } else { console.log(i + ' BYE'); } // If counter is 10 or greater run fnStop() if (i >= 10) { fnStop(); } }; function fnStop() { // Stop the interval function fnCount() clearInterval(fnCount); };