【lua函数队列】- 启动一个间隔x秒就执行的定时器

文章介绍了一个基于Lua实现的异步任务队列系统,该系统将需要执行的函数组织成队列,按照设定的时间间隔执行。相比协程,作者认为这种方案在处理业务逻辑分帧和函数批量处理时更有效。系统包括添加回调、启动、停止和重置等功能,支持自定义触发间隔和单次启动的函数数量。
摘要由CSDN通过智能技术生成

 一般情况下,我们都会有一个每隔x秒就执行的定时器。

基于这种情况下,我们可以把需要执行的函数列表做成一个队列,然后相隔x秒就调用该队列的函数。

适用于业务逻辑分帧处理、函数分批处理等等情况。

个人感觉比协程好用,推荐给大家。

下面只是一个代码流程展示,并不能直接运行


---[
--- 异步任务队列
---]
local AsyncFunList = {}

---初始化
---@param self table
---@param data AsyncFunListData 数据类型结构
function AsyncFunList.__init(self,data)
    self.callBackList = {}                      -- 执行队列
    self.nextPlayTime = 0                       -- 最后一次调用的时间戳
    self.date = data or AsyncFunListData.New()
end

-- 获取配置数据
function AsyncFunList:GetDelayTime()
    return self.data.delayTime
end

-- 销毁
function AsyncFunList:Delete()
    self.callBackList = nil
end

-- 触发结束回调
function AsyncFunList:CallEndBack()
    if nil ~= self.data.endFun then
        self.data.endFun()
    end
end

-- 添加回调进队列
---@param fun any       回调
---@param ... unknown   任意参数
function AsyncFunList:AddFun(fun,...)
    if nil == self.callBackList then
        self.callBackList = {}
    end
    table.insert(self.callBackList, {endFun = fun,arg = {...}})
    local startTime = 0
    -- 获取当前时间,伪代码,并统计下一次启动的时间间隔
    local nowTime = os.clock()
    if nowTime - self.nextPlayTime < self.data.delayTime then
        startTime = (self.data.delayTime / 1000 - (nowTime - self.nextPlayTime))
        startTime = startTime > 0 and startTime or 0
    end
    -- 伪代码 ,启动任务队列
    Time.Start(function ()
        self:Start()
    end,startTime)
end

-- 获取待启动回调列表
function AsyncFunList:GetList()
    return self.callBackList or {}
end

-- 移除某个回调
---@param pos any   需要移除的回调所在位置
function AsyncFunList:Remove(callList,pos)
    table.remove(callList,pos)
end

-- 启动回调
function AsyncFunList:Start()
    if nil == self.callBackList or 0 >= #self.callBackList then
        return
    end
    self.nextPlayTime = os.clock()

    local max = self.data.starFuntNum > #self.callBackList and #self.callBackList or self.data.starFuntNum 
    for _ = max, 1, -1 do
        local t = self:Remove(self.callBackList,1)
        if nil ~= t then
            t:endFun(t.arg)
        end
    end
    if 0 == #self.callBackList then
        --没有新的则结束
        self:Delete()
        self:CallEndBack()
    end
end

-- 恢复并触发所有的回调
function AsyncFunList:ResetAll()
    if nil ~= self.callBackList then
        local max = #self.callBackList
        for _ = max, 1, -1 do
            local t = self:Remove(self.callBackList,1)
            if nil ~= t then
                t:endFun(t.arg,true)
            end
        end
    end
    self:CallEndBack()
    self:Delete()
end


return AsyncFunList

local AsyncFunListData = {}

-- 初始化
---@param delayTime number      触发间隔时间(毫秒)
---@param endFun function       所有触发结束回调
---@param starFuntNum number    每次启动触发的数量
function AsyncFunListData:__init(delayTime,endFun,starFuntNum)
    self.delayTime = nil ~= delayTime and delayTime or 1
    self.endFun = endFun
    self.starFuntNum = nil ~= starFuntNum and starFuntNum or 1
end



return AsyncFunListData

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值