Opóźnione zdarzenia silnika

*Ta zawartość została przetłumaczona przy użyciu narzędzi AI (w wersji beta) i może zawierać błędy. Aby wyświetlić tę stronę w języku angielskim, kliknij tutaj.

Właściwość Workspace.SignalBehavior kontroluje, czy sterowniki zdarzeń są uruchamiane natychmiast lub opóźniane.Polecamy opcję Enum.SignalBehavior.Deferred, która pomaga poprawić wydajność i poprawność silnika.Menadżerowie zdarzeń dla opóźnionych zdarzeń są wznowieni na następnym punkcie wznowienia, wraz z każdym nowo uruchomionym menadżerem zdarzeń.

Poniższy diagram porównuje zachowanie wydarzenia Immediate i zachowanie wydarzenia Deferred.

  • Z zachowaniem Immediate, jeśli wydarzenie uruchamia kolejne wydarzenie, drugi obsługiwacz wydarzeń natychmiast się uruchamia.
  • Z zachowaniem Deferred, drugie wydarzenie jest dodane do tyłu kolejki i uruchamiane później.

Całkowity czas potrzebny nie zmienia się, ale kolejność jest inna.

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

„Ponowne wejście” zapobiega ciągłemu strzelaniu jeden do drugiego przez wydarzenia, gdy osiągną określoną głębokość. Obecny limit dla tego wynosi 10.

Odroczone korzyści z wydarzenia

Zachowanie Immediate ma pewne wady.Dla każdej instancji dodanej do twojej gra, właściwość, która się zmienia, lub jakiś inny uruchamiany przez nią trigger, silnik musi uruchomić kod Luau, zanim wydarzy się cokolwiek innego.

  • Aby zmienić 1000 właściwości, 1000 kawałków kodu potencjalnie musi uruchomić się po każdej zmianie.
  • Możą występowaćdziwne, trudne do zdiagnozowania błędy, takie jak usuwanie zdarzenia wystrzeliwującego przed dodaniem czegoś.
  • Systemy krytyczne pod względem wydajności mogą wysyłać zdarzenia wymagające, aby wracały i wracały do Luau.
  • Przetwarzacze zdarzeń mogą wprowadzać zmiany w miejscu lub uruchamiać inne zdarzenia za każdym razem, gdy uruchamiane jest zdarzenie.
  • Wydarzenie może wystrzelić wielokrotnie, mimo że jest zbędne, na przykład zmieniając właściwość dwa razy.

Dzięki posiadaniu określonych częściach cyklu życia silnika, w których Luau może działać, silnik może uzyskać poprawę wydajności poprzez wykorzystanie szeregu założeń:

  • Systemy krytyczne pod względem wydajności nie muszą oddawać Luau, co prowadzi do zwiększenia wydajności.
  • Chyba że sam silnik go zmieni, miejsce nigdy nie zmienia się poza punktem wznowienia.

Punkty wznowienia

Po odłożeniu, menedżer zdarzeń jest wznowiony na następnym punkcie wznowienia. Obecnie zestaw punktów wznowienia obejmuje:

Wspólne wzory zainfekowanego kodu

Z zdarzeniami zdalnymi następujące przykłady albo przestają prawidłowo działać, albo mają subtelnie różne zachowanie; polegają na tym, że zdarzenia są natychmiast wznowione.

Wyzwalaj i chwytaj zdarzenia w połowie wykonania

W tym przykładzie zawsze zwracany jest false, gdy włączone są opóźnione zdarzenia, ponieważ wezwanie nie zostało uruchomione.Aby poprawnie działać, wątek musi się zatrzymać, dopóki co najmniej wydarzenie nie zostanie uruchomione.


local success = false
event:Connect(function ()
success = true
end)
doSomethingToTriggerEvent() -- Przyczynia się do uruchomienia `event`
return success

Poczekaj na pierwszą wystąpienie zdarzenia


connection = event:Connect(function ()
connection:Disconnect()
-- zrób coś
end)

Z włączonymi opóźnionymi zdarzeniami można umieścić w kole kolejne wezwania do obsługi zdarzeń, zanim się odłączysz od zdarzenia.Wezwanie Disconnect() anuluje wszystkie oczekujące wezwania do obsługi zdarzeń - to samo zachowanie, które istnieje dla natychmiastowych zdarzeń.

Alternatywnie użyj Once() jako bardziej wygodnej metody połączenia z wydarzeniem, do którego potrzebujesz tylko pierwszego wezwania.

Wydarzenia, które zmieniają przodków lub właściwości

Opóźnione zdarzenia powodują zdarzenia, które obsługują zmianę potomstwa lub właściwości po zmianie potomstwa lub właściwości:


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

Ponieważ Destroy() działa natychmiast po wywołaniu skryptu, który go wezwał, instancja została już zniszczona przed wezwaniem onPartDestroying().Dla więcej przykładów patrz Instance.Destroying.