lua版promise实现1 - 辅助代码之消息循环

 

---@class MsgLoop
local MsgLoop = {}
MsgLoop.__cname = "MsgLoop"
MsgLoop.__index = MsgLoop


function MsgLoop.new(maxRunSec)
    local inst = {}
    setmetatable(inst, MsgLoop)
    inst:ctor(maxRunSec)
    return inst
end

function MsgLoop:ctor(maxRunSec)
    self.m_MsgQueue = {}
    self.m_MaxRunSec = maxRunSec or 0
end

---@param callback fun(data:any)
---@param delay number
---@param data any
function MsgLoop:PostRun(callback, delay, data)
    local now = os.time()
    local msg = {
        startTime = now,
        endTime = now + delay,
        cb = callback,
        data = data,
    }
    table.insert(self.m_MsgQueue, msg)
end

---开始消息循环, 执行后, 线程将阻塞
function MsgLoop:StartLoop()
    local startTime = os.time()
    while true do
        local now = os.time()
        if self.m_MaxRunSec > 0 and now - startTime >= self.m_MaxRunSec then
            break
        end

        local cnt = #self.m_MsgQueue
        local i = 1
        while i <= cnt do
            local loopItem = self.m_MsgQueue[i]
            local leftTime = loopItem.endTime - now
            if leftTime <= 0 then
                loopItem.cb(loopItem.data)
                table.remove(self.m_MsgQueue, i)
                cnt = cnt - 1
            else
                i = i + 1
            end
        end
        os.execute("ping -n 2 localhost > NUL") --Windows下sleep暂停
        --os.execute("sleep 0.1") -- Unix或Linux中sleep暂停
    end
    print("Msg Loop Exit!", os.time() - startTime)
end

return MsgLoop

 

使用代码

---@type MsgLoop
local MsgLoop = require("MsgLoop")
local _MsgLoop = MsgLoop.new(60)

_MsgLoop:PostRun(function(data)
    --2s后执行
end, 2, "TestData")

--其他逻辑,都要放在StartLoop前,StartLoop启动后,当前线程就在那里阻塞了

_MsgLoop:StartLoop()

 

posted @ 2024-08-10 00:48  yanghui01  阅读(1)  评论(0编辑  收藏  举报