Eventi del motore rinviati

*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.

La proprietà Workspace.SignalBehavior controlla se gli handler di eventi vengono sparati immediatamente o differiti.Consigliamo l'opzione Enum.SignalBehavior.Deferred 5, che aiuta a migliorare le prestazioni e la correttezza del motore.Gli handler di eventi per eventi differiti vengono ripresi al prossimo punto di ripresa, insieme a tutti gli handler di eventi appena attivati.

Il seguente diagramma compara il comportamento dell'evento Immediate e il comportamento dell'evento Deferred.

  • Con il comportamento Immediate, se un evento attiva un altro evento, il secondo gestore di eventi si attiva immediatamente.
  • Con il comportamento Deferred, il secondo evento viene aggiunto alla fine di una coda e viene eseguito più tardi.

Il tempo totale impiegato non cambia, ma l'ordine è diverso.

A comparison of three event handlers firing with Immediate and Deferred behavior

La "ri-entrata" impedisce agli eventi di sparare l'un l'altro continuamente quando raggiungono una certa profondità. Il limite attuale per questo è 10.

Vantaggi dell'evento differito

Il comportamento Immediate ha alcuni svantaggi.Per ogni istanza aggiunta al tuo Gioco, proprietà che cambia o qualche altro trigger che viene invocato, l'engine deve eseguire il codice Luau prima di qualsiasi altra cosa accada.

  • Per modificare 1.000 proprietà, 1.000 snippet di codice potrebbero potenzialmente essere eseguiti dopo ogni modifica.
  • Possono Si verificanostrani bug difficili da diagnosticare, come l'attivazione di un evento di rimozione prima che qualcosa venisse aggiunto.
  • I sistemi critici per le prestazioni possono inviare eventi che richiedono loro di andare avanti e indietro a Luau.
  • I gestori di eventi possono apportare modifiche al luogo o attivare altri eventi ogni volta che viene lanciato un evento.
  • Un evento può essere attivato più volte pur essendo ridondante, come una proprietà che cambia due volte.

Aveendo porzioni specifiche del ciclo di vita del motore in cui Luau può essere Eseguire, il motore può ottenere una migliore performance utilizzando una serie di presupposti:

  • I sistemi critici per le prestazioni non devono cedere a Luau, il che porta a guadagni di prestazioni.
  • A meno che il motore stesso non lo cambi, il luogo non cambia mai al di fuori di un punto di ripresa.

Punti di ripresa

Dopo essere stato rinviato, un gestore di eventi viene ripreso al prossimo punto di ripresa. Attualmente, il set di punti di ripresa include:

Modelli di codice interessati comuni

Con eventi remoti, i seguenti esempi smettono di funzionare correttamente o hanno un comportamento sottilmente diverso; si affidano all'evento di essere ripreso immediatamente.

Attiva e cattura eventi a metà esecuzione

In questo esempio, false è sempre restituito quando gli eventi differiti sono abilitati perché il callback non è stato Eseguire.Per funzionare correttamente, il thread deve cedere fino a quando almeno l'evento non deve essere stato attivato.


local success = false
event:Connect(function ()
success = true
end)
doSomethingToTriggerEvent() -- Causa `event` a essere Lanciare
return success

Ascolta la prima occorrenza di un evento


connection = event:Connect(function ()
connection:Disconnect()
-- fallo qualcosa
end)

Con eventi differiti abilitati, possono essere invocate più richieste di gestore di eventi prima di disconnettersi dall'evento.Chiamare Disconnect() fa cadere tutte le richieste di gestore di eventi in sospeso—lo stesso comportamento che esiste per gli eventi immediati.

In alternativa, usa Once() come metodo più conveniente per connettersi a un evento di cui hai bisogno solo della prima chiamata.

Eventi che cambiano ascendenza o proprietà

Gli eventi differiti causano eventi che gestiscono un cambiamento nell'ascendenza o una proprietà a fuoco dopo che l'ascendenza o la proprietà è stata modificata:


local part = Instance.new("Part", workspace)
local function onPartDestroying()
print("In signal:", part:GetFullName(), #part:GetChildren())
end
part.Destroying:Connect(onPartDestroying)
part:Destroy()

Poiché Destroy() funziona immediatamente dopo lo script che l'ha chiamato, l'istanza è già stata distrutta prima che venga chiamata l'ora onPartDestroying().Per altri esempi, vedi Instance.Destroying .