Mi objetivo es simular la tirada de dos dados, con la opción de "animar" la tirada o simplemente mostrar el resultado. Para esto, estoy usando el siguiente script
<script> function roll_dice() { let _die1 = Math.floor(Math.random() * 6) + 1; let _die2 = Math.floor(Math.random() * 6) + 1; let die1_img = `images/${_die1}.png` let die2_img = `images/${_die2}.png` document.getElementById("die1").setAttribute("src", die1_img); document.getElementById("die2").setAttribute("src", die2_img); } function animate_dice() { let myInterval = setInterval(roll_dice, 50); setTimeout(clearInterval(myInterval),2000); } function roll_or_animate() { if (document.getElementById("should_be_animated").checked == true) { animate_dice(); } else { roll_dice(); } } </script>con un botón que llama a roll_or_animate().
No hay problema cuando should_be_animated no está marcado, pero cuando está marcado, los dados simplemente se quedan quietos en lugar de "rodar" cada 50 ms durante 2 segundos como se esperaba. Pero si la línea
setTimeout(clearInterval(myInterval),2000);está comentado, luego los dados "ruedan" cada 50 ms, aunque sin parar.
¿Qué estoy haciendo mal? Pensé que setTimeout esperaría 2 segundos antes de ejecutar clearInterval, deteniendo así la animación continua.
Debe pasar una función de devolución de llamada como primer parámetro:
setInterval(() => clearInterval(myInterval), 2000);Con esta línea:
setTimeout(clearInterval(myInterval),2000); La clearInterval(myInterval) se ejecuta inmediatamente y cualquiera que sea el valor de retorno de esa llamada, se ejecutará después de que se alcance el retraso de 2000 ms del temporizador.
El valor de retorno de esta llamada de función no es lo que requiere el primer argumento de setTimeout() . Requiere una referencia de función. Entonces, para hacer que esa llamada espere el tiempo del temporizador, debe envolver esa llamada en una referencia de función.
setTimeout(function(){ clearInterval(myInterval) },2000);