For the complete documentation index, see llms.txt. This page is also available as Markdown.

Funções Assíncronas

Aprenda quando e como executar funções assíncronas no código da sua scene.

Visão geral

A maior parte do código na tua scene é executada de forma síncrona usando uma única thread. Isso significa que os comandos são executados sequencialmente, linha por linha. Cada comando tem primeiro de aguardar que o comando anterior termine de ser executado antes de poder começar.

Até mesmo as funções nos systems da tua scene são executadas uma a uma, seguindo uma ordem de prioridade.

Executar código de forma síncrona garante consistência, pois podes sempre ter a certeza de que saberás a ordem em que os comandos no teu código são executados.

Por outro lado, a tua scene precisa de ser atualizada muitas vezes por segundo, construindo o próximo frame. Se uma parte do teu código demorar demasiado a responder, então toda a thread principal fica bloqueada e isso resulta em frame rates mais lentos.

É por isso que, em alguns casos, queres que alguns comandos sejam executados de forma assíncrona. Isso significa que podes iniciar uma tarefa e, entretanto, a scene pode continuar a executar o restante código. A scene continua a executar tudo numa única thread, mas enquanto a tarefa assíncrona aguarda uma resposta, o restante código não fica bloqueado.

Isto é especialmente útil para tarefas que dependem de serviços externos que podem demorar a responder, já que não queres que esse tempo de inatividade à espera dessa resposta bloqueie outras tarefas.

Por exemplo:

  • Ao obter dados de uma REST API

  • Ao realizar uma transação na blockchain

Executar uma função async

Marca qualquer função como async para que seja executada de forma assíncrona, sem bloquear o restante código da tua scene enquanto aguarda.

// declarar função async
async function myAsyncTask() {
	// executar os passos da função
}

// chamar função async
myAsyncTask()

// o resto do código continua a ser executado

A função executeTask

O executeTask() a função executa uma função lambda de forma assíncrona. executeTask() permite-nos declarar e executar a função tudo numa única instrução.

A função then

O then a função recebe uma função lambda como argumento, que só é executada quando a instrução anterior termina. Esta função lambda pode opcionalmente ter entradas mapeadas a partir do que quer que a instrução anterior devolva.

Funções PointerEvents e RayCast

Quando a tua scene usa um PointerEvent ou um RayCast component, os cálculos de colisões são realizados de forma async no Engine. O Engine devolve então um evento de resultados para a scene, que pode chegar um ou vários ticks do game loop depois de o evento ter sido invocado.

Depois tens de criar um system para processar estes resultados no frame em que chegam.

Veja eventos de clique e raycasting.

💡 Dica: Se o processamento dos resultados de um raycast exigir muitos cálculos (como executar um algoritmo de path-finding), talvez queiras executar esse cálculo numa função assíncrona.

A instrução await

Uma await instrução força a execução a aguardar uma resposta antes de passar para a linha seguinte de código. await instruções só podem ser usadas dentro de um bloco de código async.

O exemplo acima executa uma função que inclui uma fetch() operação para obter dados de uma API externa. A fetch() operação é assíncrona, já que não podemos prever quanto tempo o servidor vai demorar a responder. No entanto, a linha seguinte precisa que o resultado desta operação esteja pronto antes de o podermos analisar como JSON. A await instrução aqui garante que a linha seguinte só será executada quando essa operação tiver devolvido um valor. De forma semelhante, a response.json() função também é assíncrona, mas a linha seguinte precisa que o JSON seja analisado antes de o poder registar. A segunda await instrução força a linha seguinte a ser chamada apenas quando a análise do JSON terminar, independentemente do tempo que demore.

Definir um Timeout para uma chamada de função

Use setTimeout para aguardar algum tempo antes de certas linhas de código serem executadas. Isto recebe dois argumentos:

  • A função a executar

  • A quantidade de milissegundos a aguardar antes de executar essa função

O exemplo abaixo espera 1000 milissegundos (equivalente a 1 segundo) antes de executar uma função simples que regista uma mensagem na consola.

O clearTimeout pode ser usado para cancelar a execução de uma setTimeout função que ainda está à espera de ser executada. setTimeout devolve um timer id (um número), que depois podes passar para clearTimeout. Neste caso, a variável timeoutId é obtida ao fazer o setTimeout, e depois passada para clearTimeout para o cancelar.

Atualizado