Hello, I want to present you ThreadsLimiter module.
This module will help you to do async things with limit. Let me describe methods:
.new(threadsLimit, options) -- returns instance of ThreadsLimiter class (All methods down is for this instance)
options = {
["ThrowError"] = boolean --[[
Should throw error if occured? Default value is true.
Anyway any errors are in other thread, so don't worry. (just visual purpose)
]]
}
:Launch(callback, onFinishCallback, yield, otherArgs) --[[
Calls callback (or add to queue if limit) and when finished calls onFinishCallback.
If onFinishCallback is nil, then if error occur it will be shown.
onFinishCallback signature is (status, result).
Yield mean is should yield. Yields only if current limit == limit, resumes yielded threads if callbacks queue is empty.
Yield argument must be sent!
]]
:Wrap(yield, callback, otherArgs) -- Same as launch, but onFinish is nil by default.
:SetLimit(int) -- Set new limit of threads
:WaitEnd() -- Yields untill all threads done work (not yields if work already is done)
Okay, we are done with API, now let’s look into example:
local MAX_THREADS_QUEUE = 30; local ThreadsLimiter = require(script.ThreadsLimiter).new(MAX_THREADS_QUEUE, {
["ThrowError"] = false
})
local RandomIds = {}; local Random = Random.new()
for i = 1, 100, 1 do
table.insert(RandomIds, Random:NextInteger(1, 10 ^ 7))
end
local PlayersService = game:GetService("Players")
local RandomPlayersNames = {}
for index, userId in ipairs(RandomIds) do
ThreadsLimiter:Wrap(true, function() --first argument is yield (always pass this argument, even if nil)
RandomPlayersNames[userId] = PlayersService:GetNameFromUserIdAsync(userId)
end)
end
ThreadsLimiter:WaitEnd() -- yield untill all threads done work
print(RandomPlayersNames, ThreadsLimiter)
Idk, maybe there’s already exist module like this, but anyway I hope this will help you.
I didn’t use promises because I think this is overkill.
You can get module from here: ThreadsLimiter - Roblox.
Let me know if there’s any errors, I will fix them