El setTimeout
no funciona como esperas.
La instrucción setTimeout
se "ejecuta" instantáneamente, independientemente del valor de espera que le introduzcas.
Lo que hace es guardar en la cola de eventos algo como: "Dentro de xxx segundos tengo que ejecutar el método yyy".
Así pues, en tu bucle llamas de manera seguida todos los setTimeout con el valor 1000. Se almacenan todos ellos en la cola de eventos, y dentro de un segundo se ejecutan todos a la vez.
Tienes una serie de alternativas para hacer lo que quieres:
- Solución 1: Establecer una espera variable en función del número de paso en el que estés (como en la solución aportada por Triby (esperando
i * 1000
)
- Solución 2: Utilizar recursividad y llamar a la siguiente espera una vez ha terminado la anterior.
Como ejemplo de este segundo caso, podrías tener algo así:
function dibujar_despacio(x) {
if (x < 10) {
console.log(x);
//papel.drawImage(tiranosaurio.imagen, 100, x)
setTimeout(() => dibujar_despacio(x+1), 1000);
}
}
dibujar_despacio(0)
Hay algunas diferencias importantes entre ambas soluciones.
La primera diferencia es sobre el tratamiento de errores:
En la primera solución, todos los pasos se ejecutarán incluso si existe algún error en alguno de ellos.
Con la segunda solución, si existe algún problema con papel.drawImage
por ejemplo en la iteración 6, entonces las iteraciones 7 y posteriores no se ejecutarán. Se comporta más o menos como un bucle.
La segunda diferencia es que la primera solución podría no respetar el orden si la operación de papel.drawImage
es costosa:
Por ejemplo: Pongamos que en el instante 6000ms ejecutas papel.drawImage(tiranosaurio.imagen, 100, 6)
y que esta iteración número 6 es especialmente costosa en comparación con las siguientes. Si tarda más de 1 segundo en dibujarse, podría pasar que la siguiente iteración (7) empezase antes de terminar el paso anterior. Y si fuera menos costosa, podría incluso terminar antes que el paso anterior.
Así pues, si quieres garantizar con toda seguridad un orden, porque éste es importante, te recomendaría la segunda solución.