Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

Do I have the difference from SetAsync() and UpdateAsync() correct?

Asked by
Dfzoz 489 Moderation Voter
4 years ago
Edited by Ziffixture 4 years ago

I don't know if I have got the difference of :UpdateAsync() and :SetAsync() right...

I want to show an example of how I think they should be used, can someone let me know if I am correct?


Using only SetAsync():

Player1 starts the game, and the method :SetAsync() saves this table:

{
    Money =100, 
    Life = 50, 
    Mana = 50;
}

After that, he uses :SetAsync() again to overwrite the data with this new table:

{
    Money = 150,
    Life = 75;
}

The final data:

{
    Money = 150,
    Life = 75;
}

The Mana value was removed because it wasn't supplied through :SetAsync() the second time.

1 answer

Log in to vote
3
Answered by 4 years ago
Edited 4 years ago

When you use UpdateAsync, you supply your own function that takes the argument of the player's old value. You return what the new value will be. Setting the Async will completely clear it and replace the saved data with the new one; therefore, your first example is correct. If you used UpdateAsync, it all comes down to what the function is.



SetAsync

local DataStore = game:GetService("DataStoreService"):GetDataStore("Stats")

--Assume that "plyr" is a variable of a player. This script is also supposed to be a server sided script, so you can get plyr by using events such as "PlayerAdded".

--Assume that this data store's old data was {["Money"] = 100, ["Life"] = 50, ["Mana"] = 50}

DataStore:SetAsync("User_"..plyr.UserId, {["Money"] = 150, ["Life"] = 75})

No matter what the previous data was, whether it was an integer, BrickColor or even nil, it is now completely wiped and replaced with the new information.

Here's another way to think of it:

It's like as if you had a variable and you've set it to something else.

local variable = 10
--... some lines of code later...
variable = "Now I am a string!"
print(variable)

Now I am a string!



UpdateAsync

With UpdateAsync, it works however you'd like. It takes 2 arguments: the key and then the function used to manipulate that key. The function also has a single argument which is the old value.

--Make the same assumptions as before plus the DataStore variable exists and is valid.

DataStore:UpdateAsync("User_"..plyr.UserId, function(oldTable)
    oldTable["Money"] = 150
    oldTable["Life"] = 75
    return oldTable
end)

Now in this example, the function is editing the table's contents without completely overriding it. Again, the second argument is a function; therefore, UpdateAsync does whatever you want it do.

Both UpdateAsync and SetAsync can lead to the same result

DataStore:UpdateAsync("User_"..plyr.UserId, function(oldTable)
    if oldTable then
        oldTable["Money"] = 150
        oldTable["Life"] = 75
        return oldTable
    else
        return {["Mana"] = 50} --Change this table to have all default values
        --or values of new players who are playing for the first time.
    end
end)
--Or...
local oldTable = DataStore:GetAsync("User_"..plyr.UserId) or {["Mana"] = 50} ---You can set default stats here...
oldTable["Money"] = 150
oldTable["Life"] = 75
DataStore:SetAsync("User_"..plyr.UserId, oldTable)

Both result in the same outcome.


Conclusion

So, both can do the same depending on how you code. Neat. Is there situations where you use one over the other? UpdateAsync is great, but the function that you put inside of it cannot yield at all. For example, you cannot use wait. You can use SetAsync in situations where you'd want a yield for whatever reason. UpdateAsync is great for functions where the previous value is important. For example, a function that adds 50 money every minute in the game. UpdateAsync is also better for situations where you have code that is using GetAsync and then using that information almost immediately afterwards to SetAsync. Use UpdateAsync in this case as you already get the old value by default as a variable with this function, and GetAsync can sometimes return cached or old data. If another script is changing the same DataStore with the same key, you might also want to use UpdateAsync to avoid situations where a player gets money in game, but you save money data from 30 seconds ago.

IncrementAsync is also great for a money system like this, you should look into it! It's not useful in this case, however, where the data is a table and not a number like an integer.



Hope it helps! -LordDragonZord

0
There are ways you can get "yields" inside of a function in UpdateAsync, for example: Using an infinite loop that will break after 2 tick values are more than 5 seconds apart. I am not sure about this, but I'm pretty sure WaitForChild would work too for a 5 second delay. I'm pretty sure WaitForChild does not count as a yield because it uses an infinite loop that sees if the child exists. EzraNehemiah_TF2 3552 — 4y
0
By the way, I am not recommending that you do any of this at all. Using all these infinite loops all willy nilly like this can weigh a burdon on your CPU and is just and ugly, unelegant solution. Seriously use SetAsync in those situations where you need a yield for whatever reason. EzraNehemiah_TF2 3552 — 4y
0
So, basically UpdateAsync is a neat way to use GetAsync, change the data received and SetAsync with the changes? Thanks for the help! Dfzoz 489 — 4y
0
Ultimately, :SetAsync() will override* the previous data, without taking into account of what it was before. This method of GlobalDataStore is usually used to initiate a new data storage. :UpdateAsync() will allow you to look at the current data, and decide how to change it. Ziffixture 6913 — 4y
0
"Async" means Asynchronous @LordDragonZord, it signifies the process is threaded; "Setting the Async" isn't a real term, you can find Async has a completely different meaning. Ziffixture 6913 — 4y
Ad

Answer this question