> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/patrones-de-programacion/async-functions.md).

# Funciones asíncronas

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 primero a que el comando anterior termine de ejecutarse antes de poder empezar.

Incluso las funciones en los systems de tu escena se ejecutan una por una, siguiendo un [orden de prioridad](/creator/content-creator-es/scenes-sdk7/arquitectura/systems.md#system-execution-order).

Ejecutar código de forma síncrona garantiza la coherencia, ya que siempre puedes estar seguro de que sabrás el orden en 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 se queda bloqueado y esto provoca una tasa de fotogramas lenta.

Por eso, en algunos casos querrás que algunos comandos se ejecuten de forma asíncrona. Esto significa que puedes iniciar una tarea y, mientras tanto, la escena puede seguir ejecutándose en las siguientes líneas de código. La escena sigue ejecutándolo todo en un solo hilo, pero mientras la tarea asíncrona espera una respuesta, el resto del código no se bloquea.

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

Por ejemplo:

* Al recuperar datos de una REST API
* Al realizar una transacción en la blockchain

{% hint style="warning" %}
**📔 Nota**: Ten en cuenta que podrían renderizarse varios frames de tu escena antes de que la tarea termine de ejecutarse. Asegúrate de que el código de tu escena sea lo bastante flexible como para manejar las situaciones intermedias mientras se completa la tarea asíncrona.
{% endhint %}

## Ejecutar una función async

Marca cualquier función como `async` async para que se ejecute de forma asíncrona, sin bloquear el resto del código de la escena mientras espera.

```ts
// 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

El `executeTask()` ejecuta una función lambda de forma asíncrona. `executeTask()` nos permite declarar y ejecutar la función todo en una misma instrucción.

```ts
executeTask(async () => {
	let data = await myAsyncTask()
	console.log(data)
})

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

## La función then

El `then` toma una función lambda como argumento, que solo se ejecuta una vez que la instrucción anterior ha terminado. Esta función lambda puede tener opcionalmente entradas que se asignan a partir de lo que devuelva la instrucción anterior.

```ts
myAsyncTask().then((data) => {
	console.log(data)
})
```

{% hint style="warning" %}
**📔 Nota**: Generalmente es mejor usar el `executeTask` enfoque en lugar del `then` enfoque de la función then. Si dependes demasiado de la `then` función then en varios niveles anidados, puedes acabar con lo que se conoce como "callback hell", donde el código puede volverse muy difícil de leer y mantener.
{% endhint %}

## Funciones PointerEvents y RayCast

Cuando tu escena usa un `PointerEvent` o un `RayCast` componente, los cálculos de las colisiones se realizan de forma asíncrona en el Engine. Luego el Engine devuelve un evento de resultados a la escena, que puede llegar uno o varios ticks del game loop después de cuando se invocó el evento.

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

{% hint style="warning" %}
**📔 Nota**: Si gestionas los clics a través del [**Registrar un callback**](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/register-callback.md) enfoque, no necesitas crear explícitamente un system para gestionar esto, pero ocurre lo mismo en segundo plano.
{% endhint %}

Consulta [eventos de clic](/creator/content-creator-es/scenes-sdk7/interactividad/eventos-de-button/click-events.md) y [raycasting](/creator/content-creator-es/scenes-sdk7/interactividad/raycasting.md).

{% hint style="info" %}
**💡 Consejo**: Si el procesamiento de los resultados de un raycast requiere muchos cálculos (como ejecutar un algoritmo de búsqueda de rutas) quizás quieras ejecutar ese cálculo en una función asíncrona.
{% endhint %}

## La instrucción await

Una `await` instrucción obliga a que la ejecución espere una respuesta antes de pasar a la siguiente línea de código. `await` las instrucciones solo pueden usarse dentro de un bloque de código async.

```ts
// declarar función
async function myAsyncTask() {
	try {
		let response = await fetch(callUrl)
		let json = await response.json()
		console.log(json)
	} catch {
		console.log('no se pudo llegar a la URL')
	}
}

// llamar a la función
myAsyncTask()

// El resto del código sigue ejecutándose
```

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 que la salida de esta operación esté lista antes de poder analizarla como un JSON. La `await` instrucción aquí garantiza 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é analizado antes de poder registrarlo. La segunda `await` instrucción fuerza a que la siguiente línea solo se llame una vez que haya terminado el análisis del JSON, sin importar cuánto tarde.

## Establecer un Timeout para una llamada a 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 que se va a ejecutar
* La cantidad de milisegundos que esperar antes de ejecutar esa función

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

```ts
import { timers } from '@dcl/sdk/ecs'

console.log('Esto se imprime de inmediato')

timers.setTimeout(() => {
	// función que se ejecutará después del retraso
    console.log('Esto se imprime después de 1 segundo')
}, 1000)
```

El `clearTimeout` puede usarse para cancelar la ejecución de una `setTimeout` función que todavía está esperando para ser ejecutada. `setTimeout` devuelve un id del temporizador (un número), que luego puedes pasar a `clearTimeout`. En este caso, la variable `timeoutId` se obtiene al hacer el `setTimeout`, y luego se pasa a `clearTimeout` para cancelarlo.

```ts
import { timers } from '@dcl/sdk/ecs'

const timeoutId = timers.setTimeout(() => {
    console.log('Espera 1 segundo antes de ejecutar esta función')
}, 1000)

timers.clearTimeout(timeoutId)
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-es/scenes-sdk7/patrones-de-programacion/async-functions.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
