A propriedade Workspace.SignalBehavior controla se os manipuladores de eventos são acionados imediatamente ou diferidos. A opção Enum.SignalBehavior.Deferred é recomendada, pois ajuda a melhorar o desempenho e a precisão do motor. Os manipuladores de eventos para eventos diferidos são retomados no próximo ponto de retoma, juntamente com quaisquer manipuladores de eventos recém-acionados.
O diagrama a seguir compara o comportamento de eventos Immediate e o comportamento de eventos Deferred.
- Com o comportamento Immediate, se um evento aciona outro evento, o segundo manipulador de eventos é acionado imediatamente.
- Com o comportamento Deferred, o segundo evento é adicionado ao final de uma fila e executado mais tarde.
O tempo total não muda, mas a ordem é diferente.

"A reentrância" impede que os eventos sejam acionados continuamente um ao outro quando alcançam uma certa profundidade. O limite atual para isso é 10.
Benefícios de eventos diferidos
O comportamento Immediate tem algumas desvantagens. Para cada instância adicionada ao seu jogo, propriedade que muda ou algum outro gatilho que é invocado, o motor precisa executar o código Luau antes que qualquer outra coisa aconteça.
- Para mudar 1.000 propriedades, 1.000 trechos de código potencialmente precisam ser executados após cada mudança.
- Bugs estranhos e difíceis de diagnosticar podem ocorrer, como um evento de remoção sendo acionado antes que algo fosse até adicionado.
- Sistemas críticos em desempenho podem acionar eventos exigindo que eles retornem para Luau.
- Manipuladores de eventos podem fazer mudanças no lugar ou acionar outros eventos a qualquer momento em que um evento seja acionado.
- Um evento pode ser acionado várias vezes, apesar de ser redundante, como uma propriedade mudando duas vezes.
Ao ter porções específicas do ciclo de vida do motor nas quais o Luau pode ser executado, o motor pode ganhar desempenho melhorado ao usar uma série de suposições:
- Sistemas críticos em desempenho não precisam retornar para o Luau, o que leva a ganhos de desempenho.
- A menos que o próprio motor mude, o lugar nunca muda fora de um ponto de retoma.
Pontos de retoma
Após ser diferido, um manipulador de eventos é retomado no próximo ponto de retoma. Atualmente, o conjunto de pontos de retoma inclui:
- Processamento de entrada (retoma uma vez por entrada a ser processada, veja UserInputService)
- Retoma de script legado como wait(), spawn(), e delay()
Padrões de código comumente afetados
Com eventos remotos, os seguintes exemplos ou param de funcionar corretamente ou têm um comportamento sutilmente diferente; eles dependem de eventos serem retomados imediatamente.
Acionar e capturar eventos no meio da execução
Neste exemplo, false é sempre retornado quando eventos diferidos estão habilitados porque o callback não foi executado. Para funcionar corretamente, a thread deve ceder até pelo menos o momento em que o evento deveria ter sido acionado.
local success = false
event:Connect(function ()
success = true
end)
doSomethingToTriggerEvent() -- Causa o acionamento de `event`
return success
Ouvir a primeira ocorrência de um evento
connection = event:Connect(function ()
connection:Disconnect()
-- faça algo
end)
Com eventos diferidos habilitados, várias invocações de manipuladores de eventos podem ser enfileiradas antes de você se desconectar do evento. Chamando Disconnect() descarta todas as invocações pendentes de manipuladores de eventos—o mesmo comportamento que existe para eventos imediatos.
Como alternativa, use Once() como um método mais conveniente para se conectar a um evento do qual você só precisa da primeira invocação.
Eventos que mudam a ancestralidade ou propriedades
Eventos diferidos fazem com que eventos que lidam com uma mudança na ancestralidade ou uma propriedade sejam acionados após a alteração da ancestralidade ou propriedade:
local part = Instance.new("Part", workspace)
local function onPartDestroying()
print("No sinal:", part:GetFullName(), #part:GetChildren())
end
part.Destroying:Connect(onPartDestroying)
part:Destroy()
Como Destroy() funciona imediatamente após o script que o chamou ceder, a instância já foi destruída no momento em que onPartDestroying() é chamado. Para mais exemplos, veja Instance.Destroying.