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
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.