Async Functions
Aprenda quando e como executar funções assíncronas no código da sua cena.
Visão geral
A maior parte do código na sua cena é executada de forma síncrona usando um único thread. Isso significa que os comandos são executados sequencialmente, linha por linha. Cada comando precisa primeiro aguardar que o comando anterior termine de executar antes de poder começar.
Até mesmo as funções nos sistemas da sua cena são executadas uma a uma, seguindo uma ordem de prioridade.
Executar código de forma síncrona garante consistência, pois você sempre pode ter certeza da ordem em que os comandos no seu código são executados.
Por outro lado, sua cena precisa ser atualizada muitas vezes por segundo, construindo o próximo frame. Se uma parte do seu código demorar demais para responder, então todo o thread principal fica preso e isso resulta em taxas de quadros com lag.
É por isso que, em alguns casos, você quer que alguns comandos sejam executados de forma assíncrona. Isso significa que você pode iniciar uma tarefa em um novo thread e, enquanto isso, o thread principal pode continuar executando as próximas linhas de código.
Isso é especialmente útil para tarefas que dependem de serviços externos que podem demorar a responder, já que você não quer que esse tempo ocioso aguardando a resposta bloqueie outras tarefas.
Por exemplo:
Ao recuperar dados de uma API REST
Ao executar uma transação na blockchain
📔 Nota: Tenha em mente que vários frames da sua cena podem ser renderizados antes que a tarefa termine de executar. Garanta que o código da sua cena seja flexível o suficiente para lidar com os cenários intermediários enquanto a tarefa assíncrona está sendo concluída.
Executar uma função async
Marque qualquer função como async para que ela seja executada em um thread separado do thread principal da cena sempre que for chamada.
// declarar função async
async function myAsyncTask() {
// executar passos da função
}
// chamar função async
myAsyncTask()
// o restante do código continua sendo executadoA função executeTask
A executeTask() função executa uma função lambda de forma assíncrona, em um thread separado do thread principal da cena. executeTask() nos permite declarar e executar a função tudo em uma mesma instrução.
A função then
A then função recebe uma função lambda como argumento, que só é executada uma vez que a instrução anterior seja concluída. Essa função lambda pode opcionalmente ter entradas que são mapeadas a partir do que a instrução anterior retorna.
📔 Nota: Geralmente é melhor usar o executeTask approach rather than the then function. In this example, the scene won't be considered fully loaded by the explorer till the myAsyncTask() function is completed, which may affect load times. Also, if relying too much on the then function at multiple nested levels, you can end up with what's known as "callback hell", where the code can become very hard to read and maintain.
Funções PointerEvents e RayCast
Quando sua cena usa um PointerEvent ou um RayCast componente, os cálculos de colisões são realizados de forma assíncrona no engine. O engine então retorna um evento de resultados para a cena, que pode chegar um ou vários ticks do game loop depois de quando o evento foi invocado.
Você então precisa criar um system para processar esses resultados no frame em que eles chegam.
📔 Nota: Se você tratar cliques via o Registrar um callback approach, you don't need to explicitly create a system to handle this, but the same occurs in the background.
Veja eventos de clique e raycasting.
💡 Dica: Se o processamento dos resultados de um raycast requer muitos cálculos (como executar um algoritmo de path-finding) você pode querer executar esse cálculo em uma função assíncrona.
A instrução await
Um await a instrução força a execução a aguardar uma resposta antes de passar para a próxima linha 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 um fetch() operation to retrieve data from an external API. The fetch() operation is asynchronous, as we can't predict how long the server will take to respond. However, the next line needs the output of this operation to be ready before we can parse it as a json. The await statement here ensures that the next line will only run once that operation has returned a value. Similarly, the response.json() function is also asynchronous, but the next line needs the json to be parsed before it can log it. The second await statement forces the next line to only be called once the parsing of the json is finished, however long it takes.
Definir um Timeout para a chamada de uma função
Use setTimeout para esperar algum tempo antes de certas linhas de código serem executadas. Isso recebe dois argumentos:
A função a ser executada
A quantidade de milissegundos a esperar antes de executar essa função
O exemplo abaixo espera 1000 milissegundos (igual a 1 segundo) antes de executar uma função simples que registra uma mensagem no console.
A clearTimeout pode ser usado para cancelar a execução de uma setTimeout função que ainda está aguardando para ser executada. Ao criar a setTimeout função, pegue uma referência para a função, que você pode então passar para clearTimeout. Neste caso, a variável intervalId é obtida ao fazer o setTimeout, e então passada para clearTimeout para cancelá-la.
Atualizado