Estoy aprendiendo a usar la función recursiva setTimeout .
Mi tarea es crear una función que tome 2 argumentos numéricos, from y to , e imprima cada número intermedio en la consola, uno a la vez con un retraso de 1 segundo en el medio.
Mi pregunta es, ¿por qué la función printNumbers1 no detiene la ejecución después de imprimir el número 4 en la consola? La suposición es que el timerID es incorrecto, pero no entiendo por qué.
const DELAY = 1000; const printNumbers1 = (from, to) => { let counter = from; let timerID = setTimeout(function run() { console.log(counter); counter++; if (counter > to) clearTimeout(timerID); // the function not stop the invocation without the `else` statement timerID = setTimeout(run, DELAY); }, DELAY) } const printNumbers2 = (from, to) => { let counter = from; let timerID = setTimeout(function run() { console.log(counter); counter++; if (counter > to) clearTimeout(timerID); else { timerID = setTimeout(run, DELAY); } }, DELAY) } printNumbers1(1, 4); // continues to execute after 4th invocation printNumbers2(1, 4); // stops execution after 4th invocationEsto se debe a que en el primer bloque de código, la ejecución continúa, se vuelve a llamar a setTimeout y establece otro valor de timerID.
Después de que se cumpla la condición counter > to , debe detener la ejecución o evitar que se ejecute la siguiente línea (que vuelve a llamar a setTimeout). Es por eso que el segundo bloque de código es correcto.
Cuando llama a clearTimeout, simplemente borra el temporizador establecido previamente pero no detiene la ejecución del resto del bloque de código (lo que incluye llamar a otro setTimeout en la siguiente línea de código).
Gracias por las aclaraciones @Zafer, @Teemu.
Ahora, está claro que debería haber detenido la ejecución en mi declaración if de esta manera:
const printNumbers1 = (from, to) => { let counter = from; let timerID = setTimeout(function run(){ console.log(counter); counter++; if(counter > to) return; timerID = setTimeout(run, DELAY); }, DELAY) }o, como sugirió @Teemu, invoque la función recursiva solo si la condición se cumple así:
const printNumbers1 = (from, to) => { let counter = from; let timerID = setTimeout(function run(){ console.log(counter); counter++; if(counter <= to) timerID = setTimeout(run, DELAY); }, DELAY) }