Functions:
-- Only stops yielding if specific args are passed (or timeout reached)
Await.Args(timeout, event, ...)
-- Only stops yielding when event fires (or timeout reached)
Await.Event(timeout, event)
-- Only stops yielding when one event of multiple fires, optionally with specific args passed (or timeout reached)
Await.First(timeout, ...)
General use case:
local events = {}
local timeoutDuration = 5 -- or nil
local timedOut, winnerKey, winnerArgs = Await.First(timeoutDuration, unpack(events))
if not timedOut then
print(winnerKey, "was the first event fired with these args:", winnerArgs)
else
print("no events were fired after", timeoutDuration, "seconds")
end
Use cases from my games:
Yes/no buttons
local _, winnerKey = Await.First(nil, unpack(self._yesNoButtonEvents))
if winnerKey == "yes" then
...
elseif winnerKey == "no" then
...
end
Retrieve player data timeout
local timedOut = Await.Args(10, profileLoaded.Event, player)
if timedOut then
warn("Could not retrieve profile replica for " .. player.Name .. ". Reached 10 second timeout")
return nil
end
Waiting for one event to fire before the other
local _, winnerIndex = Await.First(nil, player.Destroying, fishNameGui.Destroying)
if winnerIndex == 1 then
fishNameGui:Destroy()
end
Advanced inventory use case
-- A little context. This is apart of inventory gui code, when the player right clicks on an item
-- in their inventory, a frame pops up with options like "equip, unequip, drop, sell". The event
-- race is to determine which they click first, or if they click off of the frame (causing it to disappear),
-- or if they close the inventory all together with 'G'
local eventRaceArgs = {
{
UserInputService.InputBegan, function(input) -- This is for if the player closes the inventory or clicks somewhere else on the screen (unfocusing the current opened options frame)
return input.UserInputType == Enum.UserInputType.MouseButton1 or input.UserInputType == Enum.UserInputType.MouseButton2 or input.KeyCode == Enum.KeyCode.G
end
}
}
for _, button in ipairs(itemInteractOptions) do
button.Visible = mode:match(" " .. button.Name:lower())
if button.Visible then -- If the button is visible, then it's a viable option. We'll insert this into the event race
table.insert(eventRaceArgs, {
button.TextButton.MouseButton1Down,
Await.WinnerKey(button.Name)
})
end
end
task.spawn(function()
local _, buttonPressed = Await.First(nil, unpack(eventRaceArgs)) -- Waiting for the first event to fire
disableInteractOptionsFrame()
if type(buttonPressed) == "string" then
interactOptionCallback(buttonPressed)
end
end)
Roblox Model: Await - Roblox