Async Functions

Aprende cuándo y cómo ejecutar funciones asíncronas en el código de tu escena.

Resumen

La mayor parte del código en tu escena se ejecuta de forma síncrona usando un solo hilo. Eso significa que los comandos se ejecutan secuencialmente línea por línea. Cada comando debe esperar a que el comando anterior termine de ejecutarse antes de poder comenzar.

Incluso las funciones en los systems de tu escena se ejecutan una por una, siguiendo un orden de prioridad.

Ejecutar código de forma síncrona asegura consistencia, ya que siempre puedes estar seguro del orden en el que se ejecutan los comandos de tu código.

Por otro lado, tu escena necesita actualizarse muchas veces por segundo, construyendo el siguiente frame. Si una parte de tu código tarda demasiado en responder, entonces todo el hilo principal queda bloqueado y esto resulta en tasas de frames con lag.

Por eso, en algunos casos quieres que ciertos comandos se ejecuten de forma asíncrona. Esto significa que puedes iniciar una tarea en un nuevo hilo, y mientras tanto el hilo principal puede seguir ejecutando las siguientes líneas de código.

Esto es especialmente útil para tareas que dependen de servicios externos que podrían tardar en responder, ya que no quieres que ese tiempo inactivo esperando la respuesta bloquee otras tareas.

Por ejemplo:

  • Al recuperar datos de una API REST

  • Al realizar una transacción en la blockchain

circle-exclamation

Ejecutar una función async

Marca cualquier función como async para que se ejecute en un hilo separado del hilo principal de la escena cada vez que se llame.

// declarar función async
async function myAsyncTask() {
	// ejecutar los pasos de la función
}

// llamar a la función async
myAsyncTask()

// el resto del código sigue ejecutándose

La función executeTask

La executeTask() función ejecuta una función lambda de forma asíncrona, en un hilo separado del hilo principal de la escena. executeTask() nos permite declarar y ejecutar la función todo en una misma sentencia.

La función then

La then la función recibe una función lambda como argumento, que solo se ejecuta una vez que la sentencia previa ha terminado. Esta función lambda puede opcionalmente tener entradas que se mapean a lo que la sentencia previa retorna.

circle-exclamation

Funciones PointerEvents y RayCast

Cuando tu escena usa un PointerEvent o un RayCast componente, los cálculos de colisiones se realizan de forma async en el Engine. Luego el Engine retorna un evento de resultados a la escena, que puede llegar uno o varios ticks del game loop después de que el evento fue invocado.

Entonces necesitas crear un system para procesar estos resultados en el frame en que llegan.

circle-exclamation

Ver eventos de click y raycasting.

circle-info

💡 Consejo: Si el procesamiento de los resultados de un raycast requiere muchos cálculos (como ejecutar un algoritmo de búsqueda de caminos) podrías querer ejecutar esa computación en una función asíncrona.

La sentencia await

Una await sentencia fuerza la ejecución a esperar una respuesta antes de pasar a la siguiente línea de código. await las sentencias solo pueden usarse dentro de un bloque de código async.

El ejemplo anterior ejecuta una función que incluye una fetch() operación para recuperar datos de una API externa. La fetch() operación es asíncrona, ya que no podemos predecir cuánto tardará el servidor en responder. Sin embargo, la siguiente línea necesita la salida de esta operación para poder parsearla como json. La await sentencia aquí asegura que la siguiente línea solo se ejecutará una vez que esa operación haya devuelto un valor. De manera similar, la response.json() función también es asíncrona, pero la siguiente línea necesita que el json esté parseado antes de poder registrarlo. La segunda await sentencia fuerza que la siguiente línea solo se llame una vez que el parseo del json haya terminado, por mucho tiempo que tome.

Establecer un Timeout para la llamada a una función

Usa setTimeout para esperar un tiempo antes de que se ejecuten ciertas líneas de código. Esto toma dos argumentos:

  • La función a ejecutar

  • La cantidad de milisegundos a esperar antes de ejecutar esa función

El ejemplo a continuación espera 1000 milisegundos (equivalente a 1 segundo) antes de ejecutar una función simple que registra un mensaje en la consola.

La clearTimeout puede usarse para cancelar la ejecución de una setTimeout función que aún está esperando ser ejecutada. Al crear la setTimeout función, obtén una referencia a la función, que luego puedes pasar a clearTimeout. En este caso, la variable intervalId se obtiene al hacer el setTimeout, y luego se pasa a clearTimeout para cancelarla.

Última actualización