使用 Lua 协程处理异步回调函数

异步回调

项目使用 C++ + Lua 方式,C++ 主要编写一些底层模块,通常提供异步的方式

Lua 脚本中,使用这些 C++ 导入的模块,和异步方式编写代码

一般的一次异步调用,通常还可以编写逻辑清晰的代码

但是会有些功能会比较复杂的,一段逻辑内,会多次读写 Redis 等

使得搬砖异常吃力

回调例子

假设,我们一个这样的函数:

---@class c_model
---@field c_foo fun(_callback:fun( _ok:boolean, _result:string))

c_model.c_foo 接受一个参数 _callback 回调函数

现在希望 c_model.c_foo 可以按顺序的方式编写代码

1. 封装启动一个协程

---go 函数创建并启动一个协程
---@param _co_task function @函数原型 fun(_co:thread)
function go(_co_task)
    local co = coroutine.create(_co_task) -- 创建的协程是暂停的
    coroutine.resume(co, co)              -- 调用 coroutine.resume 激活协程执行
end

这里定义了一个 go 函数,接收fun(_co:thread)类型的函数

可以让这个函数以协程的方式运行

2. 封装 c_model.c_foo 使之成为协程函数

---封装 c_model.c_foo 异步函数,成为协程函数
---@param _co thread @协程对象
---@return boolean,string
function co_foo(_co)
    c_model.c_foo(function(_ok, _result)
        coroutine.resume(_co, _ok, _result) -- 2. 回调函数被调用后,激活本协程继续执行。并把_ok, _result传递给 yield
    end)
    return coroutine.yield()                -- 1. 主动放弃运行,本协程被切换出去
end

co_foo 函数内:

  1. coroutine.yield 先会被执行,并切出
  2. coroutine.resume , 在回调函数被执行时,会执行,并传递结果给 yield
  3. yield 这里重新被切进来, return 结果返回

使用协程,顺序编写代码的例子

---test顺序编写代码,解决回调函数造成同块逻辑被撕裂的例子
---@param _co thread @协程对象
function test(_co)
    for i = 1, 10, 1 do
        local ok, result = co_foo(_co) -- co_foo 会先 yield 切出;内部回调被执行时, resume 重新切回来继续执行
        print(ok, result)
    end
end

-- 启动 test 协程
go(test)

总结

  • 通过封装提供 go 函数,可以像 Go 语言一样,提供简易的启动协程界面
  • 项目的所有异步均可以封装提供 co_xxx 函数,使得需要回调的 API 均可以顺序编写代码。例如
    • co_sleep
    • co_rpc_call
    • co_redis_get / co_redis_set …
    • co_mysql_query
      等等

相关推荐

  1. 使用 Lua 处理异步函数

    2024-04-15 09:06:05       129 阅读
  2. Kotlin 简化

    2024-04-15 09:06:05       25 阅读
  3. Lua-coroutine

    2024-04-15 09:06:05       54 阅读
  4. Lua

    2024-04-15 09:06:05       39 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-15 09:06:05       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-15 09:06:05       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-15 09:06:05       82 阅读
  4. Python语言-面向对象

    2024-04-15 09:06:05       91 阅读

热门阅读

  1. xss常用标签和触发事件

    2024-04-15 09:06:05       36 阅读
  2. SpringBoot启动加载自己的策略类到容器中使用?

    2024-04-15 09:06:05       113 阅读
  3. Python和R概率统计算法建模评估气象和运动

    2024-04-15 09:06:05       89 阅读
  4. Qt实现Kermit协议(六)

    2024-04-15 09:06:05       42 阅读
  5. IDE:常见的集成开发环境

    2024-04-15 09:06:05       200 阅读
  6. C语言数组的初始化方法大全

    2024-04-15 09:06:05       34 阅读
  7. 软件测试Linux 必备考点

    2024-04-15 09:06:05       134 阅读