function GameEvent.pushWithFirstReturn(eventName, ...)
local eventListeners = _listeners_return[eventName]
if not eventListeners then
return nil
end
local params = {...}
for index, listeners in ipairs(eventListeners) do
release_print("事件名:"
你好,我是lua后端老师!
修仙者,你这段代码是一个自定义事件系统里带返回值的派发函数,核心逻辑是“第一个返回非nil值的监听器就中断并返回”。我来帮你优化一下。
主要优化点在于:
1. **参数传递方式**:使用 `unpack` 或 `table.unpack` 来传递变长参数,避免手动 `params[1]...params[10]` 的写法,更灵活且能处理超过10个参数的情况。
2. **循环逻辑**:将 `pcall` 和结果判断整合得更清晰。
3. **错误处理**:可以更精确地获取模块ID。
4. **特定事件处理**:`EventCfg.onAttackDamage` 的处理逻辑可以更优雅。
优化后的代码如下:
```lua
function GameEvent.pushWithFirstReturn(eventName, ...)
local eventListeners = _listeners_return[eventName]
if not eventListeners then
return nil
end
local params = {...}
for index, listenerInfo in ipairs(eventListeners) do
local listenerFunc = listenerInfo[1]
local moduleId = listenerInfo[2]
release_print(string.format("事件名:%s,开始执行监听器%d,模块ID=%s",
eventName, index, tostring(moduleId)))
-- 使用unpack传递所有参数
local success, result, stop = pcall(listenerFunc, unpack(params))
if success then
-- 如果监听器有返回值(非nil),则立即返回
if result ~= nil then
release_print(string.format("事件名:%s,监听器%d返回有效值,中断执行",
eventName, index))
return result
end
-- 如果监听器要求停止
if stop then
release_print(string.format("事件名:%s,监听器%d要求停止后续执行",
eventName, index))
break
end
-- 处理特定事件(如攻击伤害事件)的结果回写
if eventName == EventCfg.onAttackDamage then
params[5] = result
end
else
-- 错误处理
local errMsg = string.format("派发事件发生错误:事件名=%s 模块ID=%s 错误信息=%s",
eventName, tostring(moduleId), result)
release_print(errMsg)
end
end
return nil -- 所有监听器都没有返回有效值
end
```
**主要优化说明:**
1. **参数解包**:使用 `unpack(params)` 替代手动列举,代码更简洁,支持任意数量的参数。
2. **变量命名**:将 `listeners` 改为 `listenerInfo`,`listeners[1]` 改为 `listenerFunc`,提高可读性。
3. **字符串格式化**:使用 `string.format` 替代字符串拼接,使日志输出更规整。
4. **错误信息**:在错误日志中直接输出错误信息 `result`(即pcall捕获的错误信息)。
5. **逻辑微调**:将 `EventCfg.onAttackDamage` 的处理移到成功执行分支内,更符合逻辑。
这个优化保持了原有功能,同时提高了代码的健壮性和可读性。如果还有其他问题,随时问我,或者去请教浮生梦尊师!