如何无需记录触发时间/次数实现每X秒触发函数?
无状态固定周期触发方案
如果每个对象仅持有自身的lifetime(自创建起的累计时长),且希望每triggerTime(如2秒)触发一次函数,同时不存储额外的lastTime或触发次数,以下两种通用方案可以解决问题:
1. 帧间隔周期刻度判断法
利用lifetime与周期时长的数学关系,结合帧间隔时间判断是否进入新周期,完全无需对象存储额外状态。
核心逻辑:计算当前lifetime对应的周期刻度,再计算上一帧时刻的周期刻度,当两个刻度不一致时,说明刚进入新周期,触发函数。
伪代码示例:
frameDelta = getFrameDeltaTime() # 当前帧与上一帧的时间差 currentCycle = lifetime // triggerTime prevCycle = (lifetime - frameDelta) // triggerTime if currentCycle != prevCycle: doTheThing()
优势:
- 完全依赖对象自身
lifetime和全局帧间隔,无额外状态存储 - 触发时机精准对齐周期边界,不会出现重复触发或漏触发
2. 浮点余数区间检测法
如果无法获取帧间隔frameDelta,可以通过判断lifetime的余数是否落在极小区间内,实现周期触发。
核心逻辑:计算lifetime % triggerTime的余数,当余数小于当前程序的最大帧时间(或自定义极小阈值)时,触发函数。
伪代码示例:
threshold = getMaxFrameTime() # 或直接设为0.01(根据帧率调整) remainder = lifetime % triggerTime if remainder < threshold: doTheThing()
注意事项:
- 需根据程序帧率设置合理的
threshold,避免同一周期内多次触发 - 若程序存在大幅帧率波动,可能出现漏触发,此时优先选择第一种方案
关于取整/取模的误区
你之前认为取整或取模需要记录触发次数,是担心同一周期内重复触发,但通过上述两种方式,所有判断都基于当前lifetime和时间差的无状态计算,完全不需要存储对象级的状态变量。
内容的提问来源于stack exchange,提问作者Adam L.
相关产品推荐
相关产品推荐

