洛阳做天然气公司网站,南京江宁区住房建设局网站,文昌品牌网站建设费用,网址大全最安全实用的网址封装 go 函数
在 使用 Lua 协程处理异步回调函数 中已经介绍
这里简要列下#xff1a;
封装 go 函数---go 函数创建并启动一个协程
---param _co_task function 函数原型 fun(_co:thread)
function go(_co_task)local co coroutine.create(_co_task) -- 创建的协程是暂停的…封装 go 函数
在 使用 Lua 协程处理异步回调函数 中已经介绍
这里简要列下
封装 go 函数---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封装项目中异步函数---封装 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传递给 yieldend)return coroutine.yield() -- 1. 主动放弃运行本协程被切换出去
end使用例子---test顺序编写代码解决回调函数造成同块逻辑被撕裂的例子
---param _co thread 协程对象
function test(_co)for i 1, 10, 1 dolocal ok, result co_foo(_co) -- co_foo 会先 yield 切出内部回调被执行时 resume 重新切回来继续执行print(ok, result)end
end-- 启动 test 协程
go(test)封装 defer
defer 的特点有以下
协程正常退出能被执行协程异常退出能被执行同个协程内可以多次调用 deferdefer 被执行时按出栈顺序被执行
defer 多次执行
首先定义 defer 函数让它具备能多次被调用
function defer(_co_wrap, h)table.insert(_co_wrap.defer_handlers, h)
end因为要对 defer 的函数句柄做保持以便退出时执行。包裹了下 co 对象
---class co_wrap
---field co thread
---field defer_handlers fun(_co_error:co_error)[]同时定义下让 defer 的函数知道是否有错误的对象
---class co_error
---field ok booleandefer 被执行时按出栈顺序被执行
function invoke_defer_handlers(_co_wrap, _co_error)for i#_co_wrap.defer_handlers, 1, -1 dolocal h _co_wrap.defer_handlers[i]xpcall(h, function(err) print(err) end, _co_error)end
end协程异常时能被执行
Lua 协程异常通过 coroutine.resume 捕获并返回错误信息
因此主要封装下 coroutine.resume :
function coroutine_resume(_co_wrap, ...)local ok, errmsg coroutine.resume(_co_wrap.co, ...)if not ok theninvoke_defer_handlers(_co_wrap, {okfalse}) -- 异常退出end
end协程正常退出时能被执行
function go(_co_task)local co coroutine.create(function(_co_wrap)_co_task(_co_wrap)invoke_defer_handlers(_co_wrap, {oktrue}) -- 正常退出end)local cowrap { co co, defer_handlers {} } ---type co_wrapcoroutine_resume(cowrap, cowrap) -- 初创建的协程是暂停的手动触发执行
end以上就可以在 Lua 中完全 Golang 的方式编写协程代码了
协程间通信
由于项目中暂时是一根线程管理一个 lua_state 对象因此暂时无需求多线程中的协程间的通信需求
待续