RBXScriptSignal:Wait(t: number?)

As the title says, a feature to dictate how long the thread waits for the script signal until it resumes. If the field is left empty simply yield indefintely, if not, it yields for the amount of time given, then removes itself.

Benefits: No need for custom coroutine functionality in order to get around this, and would prove to be very helpful in systems where clients wait for server responses and need to only wait a specific window of time for a packet.

23 Likes

Support. I love this idea, and it would help a lot to avoid indefinitely yielded scripts.

I would think of a simple workaround such as this:

local fired = false
local connection = RBXScriptSignal:Connect(function()
    fired = true
end)

task.wait(4)
if not fired then connection:Disconnect() end

But sure, that sounds interesting and could be doable.

This would delay for 4 seconds regardless of whether the event has fired or not, which is not the behavior they’re looking for.
They’re looking for something that lets them wait for the signal or fire or after X seconds pass, whichever happens first (so if we’re giving this a “timeout” of 10 seconds, but the event fires after 2, we only wait 2 seconds instead of the full 10)

Wouldn’t something like this work

local function Wait(sig: RBXScriptSignal, timeout: number?) : ( ...any ) 
    local conn
    local timeoutThread

    local mainThread = coroutine.running()

    conn = sig:Once(function(...)
        if timeoutThread and coroutine.status(timeoutThread) == "suspended" then
            task.cancel(timeoutThread)
        end
        task.spawn(mainThread, ...)
    end)
    
    if timeout then
        timeoutThread = task.delay(timeout, function()
            if conn.Connected then
                conn:Disconnect()
                task.spawn(mainThread)
            end
        end)
    end

    return coroutine.yield()
end

@IIIIlIIlllIlIlll . That is a solution! But I feel Roblox should have this natively.

Please don’t be a mumbler, this is not impossible

local function waitSignal(signal: RBXScriptSignal, timeout: number, handler: () -> ())
	local timeoutThread: thread?
	local connection = signal:Once(function()
		task.cancel(assert(timeoutThread))
		handler()
	end)

	timeoutThread = task.delay(timeout, function()
		connection:Disconnect()
		handler()
	end)
end

Could you please provide a sample use case when do you need this?
Thank you!

This would serve pretty much exact solution, as the :WaitForChild() timeOut parameter. Having to create a function would either:
a) require developers to clone same code over multiple scripts (bad practise), or
b) create a seperate module, which is then required by the script.
These options just create unnecessary overhead and boilerplate, which could be easily added by Roblox. Though I wish signal libraries would add this as well.

3 Likes

I agree, this would be very good for some systems that needs to wait for an event but also can’t just stop everything for an indefinite amount of time to wait for it.

3 Likes

You do realize that this logic:

  • wait for signal
  • or time out it after N seconds
  • either way call a handler

does not require waiting for anything at all, right?
just call the handler with N seconds delay, or without delay at all, because essentially it does not matter.

Not saying your implamentation has anything wrong, it’s just that this method could be implamented natively, just like :WaitForChild().

4 Likes

Hi af_2048! I made this with the purpose of removing unnecessary abstraction. I mentioned that it is possible to do this without Roblox and using coroutines, but I feel that this should be natively introduced through the method itself. There isn’t really a reason not to do it, and it would save some time from the developer having to abstract the function further.

As for the use case, it’s really anytime you would want to abstract this function for the purposes of removing its infinite yield state.

You are correct in seeing that it might seem redundant, so thank you for pointing that out! I think it would remove code complexity personally, and make it easier for everyone at all levels to use this natively.

3 Likes