Yuan.Changed:Connect(function() wait(10) datast1:SetAsync(plr.UserId, Yuan.Value) print('Data has been saved') repeat until game.Players.PlayerRemoving:Connect(function() end) end)
From chatting with you I now suspect that Yuan
changes whenever you are in contact with a part (via a Touched event). Touched events can trigger many times per second -- attempting to call SetAsync every time that that happens is going to have throttling problems regardless of if you wait 10 seconds before doing it. Importantly, note that every time an event occurs, it will start a new coroutine (also known as 'thread') to run your function (you might think of it like a "copy" or "instance"); they can all wait for 10 seconds simultaneously.
Note that your repeat until
loop is not good. You only want to use repeat until
if you want to repeat something until a condition is true (but you aren't repeating anything -- not even a 'wait()' command, which would be required to prevent Roblox from freezing in the event that the condition you are checking in the 'until' part is false
/nil
). I suspect you are trying to say (in English) "wait until the player has left before trying to save again", but all that code does is create a memory leak: the Connect
function returns a Connection
object (which will be considered true
by the repeat loop causing it stop looping, which is why your game didn't freeze up). Now, you don't store this connection in a variable, but it's still remembered by the event you connected to, and thus will stay in memory even though you don't need it.
To fix this, the plan I recommend is to allow only one thread to save at a time and to allow one more thread to wait for the first one to save (and wait for the 10 second cooldown to pass) before itself saving. If any other threads come along, they shouldn't do anything.
local YuanDB = false -- true if a thread is in the process of saving local YuanWaiting = false -- true if a thread is waiting for a chance to save Yuan.Changed:Connect(function() if YuanWaiting then return end -- this function is being run and another thread is waiting to run YuanWaiting = true while YuanDB do wait(1) end YuanWaiting = false YuanDB = true local success, msg = pcall(function() datast1:SetAsync(plr.UserId, Yuan.Value) end) if success then print('Data has been saved') else print('Data failed to save. Error message:", msg) end wait(10) YuanDB = false end)
Note the pcall
I added. SetAsync can error even if you give it proper data. If it were to error here, YuanDB would be stuck as true
, preventing this value from ever saving again (for this player while on this server). Using pcall
avoids that possibility.