一般情况下,我们都会有一个每隔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