Eventos de motor retrasados

*Este contenido se traduce usando la IA (Beta) y puede contener errores. Para ver esta página en inglés, haz clic en aquí.

La propiedad Workspace.SignalBehavior controla si los manipuladores de eventos se disparan inmediatamente o se retrasan.Recomendamos la opción Enum.SignalBehavior.Deferred que ayuda a mejorar el rendimiento y la corrección del motor.Los manipuladores de eventos para eventos aplazados se reanudan en el siguiente punto de reanudación, junto con cualquier manipulador de eventos recién activado.

El siguiente diagrama compara el comportamiento del evento Immediate y el comportamiento del evento Deferred.

  • Con el comportamiento Immediate, si un evento activa otro evento, el segundo manipulador de eventos se activa inmediatamente.
  • Con el comportamiento Deferred, el segundo evento se agrega al fondo de una cola y se ejecuta más tarde.

El tiempo total tomado no cambia, pero el orden es diferente.

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

La "reentrada" evita que los eventos disparen uno al otro continuamente cuando alcanzan una cierta profundidad. El límite actual para esto es 10.

Beneficios de evento diferidos

El comportamiento de Immediate tiene algunas desventajas.Para cada instancia agregada a tu juego, la propiedad que cambia o algún otro gatillo que se invoque, el motor debe ejecutar código Luau antes de que suceda cualquier otra cosa.

  • Para cambiar 1,000 propiedades, 1,000 fragmentos de código potencialmente deben ejecutarse después de cada cambio.
  • Pueden producirseerrores extraños y difíciles de diagnosticar, como un evento de eliminación que se dispara antes de que se agregara algo.
  • Los sistemas críticos de rendimiento pueden disparar eventos que requieren que devuelvan de ida y vuelta a Luau.
  • Los manipuladores de eventos pueden hacer cambios en el lugar o desencadenar otros eventos cada vez que se dispara un evento.
  • Un evento puede disparar varias veces a pesar de ser redundante, como un cambio de propiedad dos veces.

Al tener porciones específicas del ciclo de vida del motor en las que Luau puede ejecutarse, el motor puede obtener un rendimiento mejorado al usar una serie de supuestos:

  • Los sistemas críticos de rendimiento no necesitan ceder a Luau, lo que conduce a ganancias de rendimiento.
  • A menos que el motor mismo lo cambie, el lugar nunca cambia fuera de un punto de reanudación.

Puntos de reanudo

Después de ser aplazado, un manipulador de eventos se reanuda en el siguiente punto de reanudación. Actualmente, el conjunto de puntos de reanudación incluye:

Patrones de código afectados comunes

Con eventos remotos, los siguientes ejemplos dejan de funcionar correctamente o tienen un comportamiento sutilmente diferente; confían en que se reanuden los eventos inmediatamente.

Activar y capturar eventos en medio de la ejecución

En este ejemplo, false siempre se devuelve cuando se habilitan eventos diferidos porque el llamado de devolución no se ha ejecutar.Para funcionar correctamente, el hilo debe ceder hasta que al menos cuando el evento debería haberse disparado.


local success = false
event:Connect(function ()
success = true
end)
doSomethingToTriggerEvent() -- Causa que el `evento` se desencadenar
return success

Escuchar la primera ocurrencia de un evento


connection = event:Connect(function ()
connection:Disconnect()
-- hacer algo
end)

Con eventos diferidos habilitados, se pueden programar múltiples invocaciones de manejador de eventos antes de que te desconectes del evento.Llamar Disconnect() cancela todas las invocaciones pendientes de manejadores de eventos, el mismo comportamiento que existe para eventos inmediatos.

Alternativamente, utilice Once() como un método más conveniente para conectarse a un evento al que solo necesita la primera invocación.

Eventos que cambian el ancestro o las propiedades

Los eventos retrasados causan eventos que manejan un cambio en la ascendencia o una propiedad para disparar después de que la ascendencia o la propiedad se cambie:


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

Debido a que Destroy() funciona inmediatamente después de que el script que lo llamó se rinda, la instancia ya se ha destruido para el momento en que se llame onPartDestroying().Para más ejemplos, vea Instance.Destroying .