He escrito una pequeña función para animar algunas cadenas de varias líneas. Toma una matriz de cadenas que registrará. Utiliza el intervalo establecido para ejecutar la función que registrará los cuadros. Luego, cuando no quedan marcos, se ejecuta un intervalo claro y se llama a una función de devolución de llamada. En mi caso, la función de devolución de llamada utiliza el módulo readlineSync para esperar la entrada del usuario (es decir, el usuario puede seleccionar continuar o salir). Luego, el script espera la entrada del usuario. Al seleccionar continuar, se llamará a la siguiente función; al seleccionar salir, se saldrá.
Básicamente, se ejecuta según lo previsto si después de que comienza la animación, el usuario no presiona ningún botón. Pero si el usuario presiona la tecla 1 (la tecla continuar) durante la animación, una vez que la animación finaliza, el indicador readlineSync parpadea brevemente y usa esa entrada y continúa (lo mismo ocurre con la tecla 2 y salir).
Lo que no entiendo es cómo está usando la entrada antes de que se llamara. Sé que este no es un caso de uso súper convencional para el nodo, pero realmente me gustaría entender qué está sucediendo y si hay una manera de hacer que esto funcione como se desea.
readlineSync me ha funcionado durante todo el proyecto, y también he usado el bucle setInterval para otras cosas, como la lógica del juego, sin ningún problema. Parece que solo es un problema cuando setInterval y readlineSync se usan en conjunto.
Aquí está el enlace al módulo: https://www.npmjs.com/package/readline-sync
Aquí está mi código simplificado. Gracias de antemano por cualquier ayuda para la comprensión!
Const readlineSync = require("readline-sync") let myArray = ["testing", "this", "function"]; let animate = function(array, fps, callback){ let numberOfFrames = array.length; let index = 0; let animationLoop = function(){ console.clear(); console.log(array[index]); index++; numberOfFrames--; if(numberOfFrames === 0){ clearInterval(animationLoopInterval); callback(); } } animationLoopInterval = setInterval(animationLoop, 1000/fps); }; let next = function(){ let answer = readlineSync.keyInSelect(["Continue", "Exit"]); if(answer === 0){ console.log("Unfortunately this runs from input that came during the animation") }else if(answer === 1){ process.exit(); } }; animate(myArray, 1, next);
Ese es el comportamiento natural de la CLI, si el usuario ingresa al terminal mientras su aplicación no recibe la entrada, los datos se almacenan en búfer y todos los datos se envían a su aplicación en el momento en que comienza a leer las entradas (cuando llama a readlineSync.keyInSelect
)
Una opción para resolver esto es hacer que su aplicación siempre escuche los datos del usuario, incluso cuando no espera ninguna entrada.
Poner esta sola línea antes de la función de animate
debería obtener el comportamiento deseado:
process.stdin.on("data", ()=>{})