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

Callbacks cannot yield?

Asked by
unmiss 337 Moderation Voter
8 years ago

I have this money giving system and it bases how much money they receive on what team they are on. I keep getting the error that callbacks cannot yield. I'm quite confused as I don't get this error if I remove those "ifs" regarding whether they're on a specific team or not.

local DS = game:GetService("DataStoreService"):GetDataStore("CoB_Money3")

x = 50

game.Players.PlayerAdded:connect(function(plr)
    while x <= 50 and x > 0 do
        wait(1)
        x = x - 1
        plr.PlayerGui.Menu_UI.Main.Wait.Text = x.."s"
        if x == 0 then
            x = 50
            DS:UpdateAsync("user_"..plr.userId, function(o)
                local n = o or 0
                if plr.TeamColor == BrickColor.new("Smoky grey") and not plr:IsInGroup(2634853) then -- If they're not in Broadview
                    return n + 10
                elseif plr.TeamColor == BrickColor.new("Smoky grey") and plr:IsInGroup(2634853) then -- If they're a citizen of Broadview
                    return n + 15
                elseif plr.TeamColor == BrickColor.new("Deep blue") then -- If they're on the BPD team
                    return n + 20
                elseif plr.TeamColor == BrickColor.new("Persimmon") then -- If they're on the BFD team
                    return n + 20
                end
            end)
        end
    end
end)

1 answer

Log in to vote
2
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
8 years ago

Breaking down the error

Callback

A callback is a function you give away hoping that it will be called later. In this case, it's the function(o) that you give to UpdateAsync

yield

A yield occurs when the script pauses. wait() is the most common way that happens.

In this case, the yield is actually caused by :IsInGroup -- ROBLOX has to pause because it needs to spend time asking the website if you're in a given group.

UpdateAsync requires that this doesn't happen, so you can't use :IsInGroup inside of this function.


Solution

The solution is to compute plr:IsInGroup(2634853) before the callback. It could look something like this:

        if x == 0 then
            x = 50
            local inGroup = plr:IsInGroup(2634853)
            DS:UpdateAsync("user_"..plr.userId, function(o)
                local n = o or 0
                if plr.TeamColor == BrickColor.new("Smoky grey") and not inGroup then -- If they're not in Broadview
                    return n + 10
                elseif plr.TeamColor == BrickColor.new("Smoky grey") and inGroup then -- If they're a citizen of Broadview
                    return n + 15
                elseif plr.TeamColor == BrickColor.new("Deep blue") then -- If they're on the BPD team
                    return n + 20

Cleanup

I notice that the condition of your while loop isn't really necessary -- x will always be between 0 and 50. I recommend writing ranges out in order, by the way: 0 < x and x <= 50. It makes it much easier to understand.

The way you check, decrease, and reset x is a little clunky -- a for loop would get that for you for free. I recommend shaping it like this:

local DS = game:GetService("DataStoreService"):GetDataStore("CoB_Money3")

game.Players.PlayerAdded:connect(function(plr)
    while true do
        for t = 50, 0, -1 do
            plr.PlayerGui.Menu_UI.Main.Wait.Text = t .. "s"
            wait(1)
        end
        local inGroup = plr:IsInGroup(2634853)
        DS:UpdateAsync("user_" .. plr.userId, function(o)
            local n = o or 0
            if plr.TeamColor == BrickColor.new("Smoky grey") and not inGroup then -- If they're not in Broadview
                return n + 10
            elseif plr.TeamColor == BrickColor.new("Smoky grey") and inGroup then -- If they're a citizen of Broadview
                return n + 15
            elseif plr.TeamColor == BrickColor.new("Deep blue") then -- If they're on the BPD team
                return n + 20
            elseif plr.TeamColor == BrickColor.new("Persimmon") then -- If they're on the BFD team
                return n + 20
            end
        end)
    end
end)
0
I really appreciate the answer-I did not realize that IsInGroup was the function yielding this. Thanks! unmiss 337 — 8y
Ad

Answer this question