Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How do you wait for a thread to be done ?

Basically I want "Loaded" to be set to true when all of the threads have been ran AND finished (aka the spawn function you can see there). How would I go about doing that efficiently ?

while true do
	for i,v in ipairs(DataStorePages:GetCurrentPage()) do
		spawn(function()
			local BlockData
		        local success2, errorMessage2
			success2, errorMessage2 = pcall(function()
				BlockData = BlocksDatastore:GetAsync(v.key)
			end)
			if success2 then
			    LoadBlock(BlockData)
			else
			    table.insert(FailedDataCache, v.key)
			end
		end)	
	end
		
	if DataStorePages.IsFinished == false then
		DataStorePages:AdvanceToNextPageAsync()
	else	
		break
	end
end
	
	Loaded.Value = true

1 answer

✓ Accepted answer

You can create counter, every time you spawn something, increase the counter by 1, at the end of the function, decrease the counter back by 1, this means counter won't be 0 while at least single thread is active, then you can repeatedly wait until counter ain't 0:

local count = 0

while true do
    for i,v in ipairs(DataStorePages:GetCurrentPage()) do
        spawn(function()
            count += 1

            local BlockData
                local success2, errorMessage2
            success2, errorMessage2 = pcall(function()
                BlockData = BlocksDatastore:GetAsync(v.key)
            end)
            if success2 then
                LoadBlock(BlockData)
            else
                table.insert(FailedDataCache, v.key)
            end

            count -= 1
        end)    
    end

    if DataStorePages.IsFinished == false then
        DataStorePages:AdvanceToNextPageAsync()
    else    
        break
    end
end

while count ~= 0 do
    task.wait()
end

Loaded.Value = true

However if i leave the while not something do task.wait() end is non-professional, the code won't just wait once, it will repeatedly wait every frame, of course you won't see performance difference but who cares, other simple way better than this is by using BindableEvent:

local finished = Instance.new("BindableEvent")
local count = 0

while true do
    for i,v in ipairs(DataStorePages:GetCurrentPage()) do
        spawn(function()
            count += 1

            local BlockData
                local success2, errorMessage2
            success2, errorMessage2 = pcall(function()
                BlockData = BlocksDatastore:GetAsync(v.key)
            end)
            if success2 then
                LoadBlock(BlockData)
            else
                table.insert(FailedDataCache, v.key)
            end

            count -= 1
            finished.Event:Fire()
        end)    
    end

    if DataStorePages.IsFinished == false then
        DataStorePages:AdvanceToNextPageAsync()
    else    
        break
    end
end

while count ~= 0 do
    finished.Event:Wait()
end

Loaded.Value = true

That way it will only check if count isn't 0 every time finished is fired, that is every time spawn thread ends since i added the :Fire there. :Wait is a function that waits until :Fire is executed.

This discussion is preserved as it was. New answers, comments, and votes are closed.