FiveM车辆升级扣费代码异常:为何先执行if再执行MySQL.Async.fetchAll?
问题解决:车辆升级扣费逻辑异步执行顺序错误
问题原因
核心问题是异步操作的执行顺序:MySQL.Async.fetchAll是异步非阻塞方法,调用后会立即返回,主线程会继续执行后续的print(pago)和if pago判断逻辑,而回调函数内的代码要等数据库查询结果返回后才会触发。这就导致判断pago时,它还是初始的false值,异步回调里的赋值根本没来得及生效。
另外代码还有两处错误:
- UPDATE语句逻辑错误:
SET money = money不会修改数据库数值,应改为SET money = @money - 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
相关产品推荐
相关产品推荐

