You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FiveM车辆升级扣费代码异常:为何先执行if再执行MySQL.Async.fetchAll?

问题解决:车辆升级扣费逻辑异步执行顺序错误

问题原因

核心问题是异步操作的执行顺序:MySQL.Async.fetchAll是异步非阻塞方法,调用后会立即返回,主线程会继续执行后续的print(pago)和if pago判断逻辑,而回调函数内的代码要等数据库查询结果返回后才会触发。这就导致判断pago时,它还是初始的false值,异步回调里的赋值根本没来得及生效。

另外代码还有两处错误:

  1. UPDATE语句逻辑错误:SET money = money不会修改数据库数值,应改为SET money = @money
  2. UPDATE语句参数错误:@shopID使用了未定义的shopID变量,需和查询时保持一致(示例中为'1')

修复后的代码

将所有依赖pago的逻辑(保存车辆、发送日志、触发客户端事件)移到异步回调函数内部,确保数据库操作完成后再执行后续流程:

AddEventHandler('Mechanic:PayModifications', function(preco,id,vehprops)
    local config = Config.TunningLocations[id]
    local _source = source
    local pago = false
    local xPlayer = ESX.GetPlayerFromId(_source)
    local societyAccount

    if config.used == _source then
        local permitido = true
        if config.job then
            permitido = false
            if xPlayer.getJob().name == config.job then
                permitido = true
            end
        end
        if permitido then
            if config.society and config.job then

                MySQL.Async.fetchAll("SELECT money FROM t1ger_mechanic WHERE shopID = @shopID", {['@shopID'] = '1'}, function(data)
                    -- 增加空值判断,避免查询结果为空时报错
                    if data[1] and data[1].money ~= nil then 
                        societyAccount = data[1].money
                    end
        
                    print(societyAccount)           
                    local newmoney = (societyAccount - preco)           
                    print(newmoney)        
        
                    if societyAccount >= preco then 
                        pago = true
                        -- 修正UPDATE语句的参数与赋值逻辑
                        MySQL.Async.execute('UPDATE t1ger_mechanic SET money = @money WHERE shopID = @shopID', { 
                            ['@shopID'] = '1', 
                            ['@money'] = newmoney 
                        })
                    end

                    -- 所有依赖pago的逻辑移到回调内部执行
                    print(pago)
                    if pago then
                        print("sucesso")
                        SaveVehicle(vehprops)
                        if Config.WebHook and Config.WebHook ~= "" then
                            sendToDiscord('Mechanic Upgrade/Tuning Logs', "[Upgrade/Tuning Logs]\n\nTotal: ".. preco .."\n\nVehicle Plate Number: [".. vehprops.plate .."]\nMechanic that worked on the vehicle: " .. xPlayer.name, 11750815)
                        end
                    end
                    TriggerClientEvent("Bennus:PayAfter",_source,pago)
                end)

            end
        end
    end
end)

额外说明

  • 异步操作的核心规则:回调函数内的代码会在数据库操作完成后执行,所有依赖数据库结果的逻辑必须放在回调内部
  • 新增data[1]的空值判断,避免数据库无返回结果时触发nil错误

内容的提问来源于stack exchange,提问作者José Pedro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:54:53