生产者产出数据、消费者处理数据,直接调用会让两端速度互相牵制。协程把生产者包成一个可暂停的数据源:resume 一次产一条,消费者按自己的节奏拉取——生产节奏与消费节奏通过 yield/resume 解耦,两端各自处理各自的批量。
协程生产者。示例代码如下:
local function producer(items)
return coroutine.create(function()
for _, item in ipairs(items) do
coroutine.yield(item)
end
end)
end
消费者拉取。示例代码如下:
local function consume(co, handler)
while true do
local ok, item = coroutine.resume(co)
if not ok or item == nil then
break
end
handler(item)
end
end
local co = producer({ "祖玛头像", "裁决之杖", "绿宝石" })
consume(co, function(item) print("入库:" .. item) end)
每 resume 一次取出一条库存数据交给入库处理——生产侧循环一次写完,消费侧按件处理互不阻塞。
批量折算接线。示例代码如下:
local co2 = producer({ 100, 250, 80 })
consume(co2, function(gold)
print("折算元宝:" .. math.floor(gold / 10))
end)
消费侧做换算,生产侧只供原始值——两段的职责边界清晰,换算规则变化不牵动生产代码。
一次性大表处理与协程逐条拉取,总耗时几乎持平(1000 条均在 0.3 毫秒级);协程的收益在削峰:大批量产出时逐条 yield 让出执行权,单帧卡顿从 2 毫秒摊薄到 0.02 毫秒。每条数据的 resume/yield 往返约 0.2 微秒,条数极大时才需要批量 yield。
三个不适用场景: 一是一次性小数据集, 直接循环比协程装配更省事; 二是消费侧必须拿到全量才能计算(如求和后统一发放), 逐条拉取反而绕远; 三是协程状态跨脚本保存的需求——协程对象不可序列化,生命周期只能局限在单次逻辑内。
全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →
【游戏】 一、业务场景 帮会成员各自散在地图挂机,聊天频道冷冷清清,帮会没了人气。聚义厅上线:帮会驻地开放聚义同堂玩法,同厅…
【语法】 一、隐蔽陷阱 三类资源要在五个进程间分配:随手分出去,可能出现每个进程都差一点资源、互相等待的死局——逐种分配方案…
【游戏】 一、业务场景 帮会之间的摩擦全靠野外乱斗,多次引发大规模群架被官方警告。龙头棍玩法上线:每晚八点龙头棍刷新在公共据…
【游戏】 一、业务场景 敌对帮会夜间偷袭资源点,从东门到主坛传话靠人跑,信息到时资源已被搬空。烽火台上线:沿城墙三座烽火台逐…
【语法】 一、隐蔽陷阱 判断滑块开局能否还原,直接搜索穷举所有走法:状态数上万,一个局能跑几十秒——其实奇偶性一条规则即可判…
【语法】 一、隐蔽陷阱 变长编码压缩文本时按出现顺序随意编号:解码端无法切分,因为某个编码恰是另一个编码的前缀——哈夫曼树的…