Use-case
Let’s say you wanted to implement your own WaitForChild, with a timeout. How would you accomplish this?
- Listen on ChildAdded
- Spawn a thread that is delayed for the given timeout duration
- Use a BindableEvent to block, which will be resumed by either ChildAdded or the timeout thread
Next,
- You call WaitForChild with a timeout of a million seconds.
- The child is added and WaitForChild returns it as expected.
Problem
The delayed timeout thread still exists, and will not stop existing for a million seconds. The thread cannot be removed from the queue. None of the thread’s upvalues can be garbage collected. Memory inflates. Fire rains down from the heavens.
Solution: Loop it
Using a loop will either be inefficient (wait()
) or inaccurate (wait(10)
). It isn’t applicable where both efficiency and accuracy are needed.
Solution: Hack actual WaitForChild timer
- WaitForChild on an object
- Use blocking as timeout delay
- Add a child to the object to cancel
- Go cry in a corner for what you had to do
Solution: Timer
-
Function Timer:Start(duration)
: Set the timer to fire after a given duration. -
Function Timer:Stop()
: Cancel the timer, preventing it from firing. -
Function Timer:IsRunning()
: Return whether the timer is currently running. -
Event Timer.Fired(actualDuration, gameTime)
: Fires after the duration has passed.