How to await for the end of a spawn/coroutine function

Heyo,

I’m a professional Full-Stack developer.
Theres a functionality that I know I can do in many other/frameworks languages.
A great example of what I need is

  1. Start loading 20 items asynchronously (for example, in web, start loading 20 images)
  2. Wait for all of them to finish
  3. Run some function (for example, stop showing loading screen)

This is often better than loading items one by one, and then running that function

Could I do the same in roblox studio?

Essentially, I’m asking, is there an easy way of checking when a spawn/coroutine function has finished?

Obviously, I know I could do a custom implementation of this.
(e.g. I know I can save a variable outside, and then just increment it each time a spawn function finished, and that way I can tell that all of them are finished)
But I’d rather not resort to such coding. I want to see if maybe someone knows of a built-in solution.

In case anyone cares, in javascript this would be done like this

await Promise.all([oneFunction(), secondFunction()...]);

or

let spawnFunctions = []
while (condition) {
spawnFunctions.push(spawnFunction())
}
await Promise.all(spawnFunctions);

I can’t find anything like this either. If it were up to me I’d have made something like task.join().

1 Like

Yeah, most languages allow you to treat these functions as “promises” or “futures”, and giving that its its own type, you can have a list of those types, and then await for the entire list.
That would be the ideal situation here.

For this, you can use Signals, like so:

local coroutineDone = Signal.new()

function doCoroutine()
	task.spawn(function()
		-- Do some work here, yielding is fine... --
		coroutineDone:Fire(result)
	end)
end

coroutineDone:Connect(function(result)
	print(result)
end)

doCoroutine()

Please see Signal API: Signal | RbxUtil

1 Like

A way I can think of achieving this is using event driven programming. Basically have a shared bindable event between said tasks, and when each one finishes, fire it with the thread that finished as a parameter(or none if you don’t need it). Have code outside of your loop that runs on each event of said bindable event and uses a variable n that is initialized at zero. If n is smaller than the amount of total threads that must run then increase it by one, else run the code that must run at the the end of all tasks and unbind the connection of that event.

I’m pretty sure you can make some sort of custom library based on that logic.

Edit: Just realized this is an old post, my bad. Will still leave the reply tho in case anyone needs it.

2 Likes