Lua-Async
這是一個基於協程的異步調用庫, 該庫的設計思路類似JavaScript的Promise, 但相比Promise, 它有更多的靈活性.
-- 引入Async
local Async = require("Async")
-- 創建Async
-- 可傳遞參數到接下來的調用中
Async.New(...)
-- 注冊異步調用
Async.New(...)
:Ok(function(ok, no, ...) return no() end) -- 在Ok管道注冊回調, 之后進入No管道
:No(function(ok, no, ...) return ok() end) -- 在No管道注冊回調, 之后進入Ok管道
:Ok(function(ok, no, ...) return no() end) -- 在Ok管道注冊回調, 之后進入No管道
:No(function(ok, no, ...) return ok() end) -- 在No管道注冊回調, 之后進入Ok管道
-- 異常捕獲
Async.New(...)
:Error(function() print("捕獲異常...") end) -- 注冊異常捕獲函數
:Ok(function(ok, no, ...) return no() end) -- 在Ok管道注冊回調, 之后進入No管道
:No(function(ok, no, ...) return ok() end) -- 在No管道注冊回調, 之后進入Ok管道
:Ok(function(ok, no, ...) return no() end) -- 在Ok管道注冊回調, 之后進入No管道
:No(function(ok, no, ...) return ok() end) -- 在No管道注冊回調, 之后進入Ok管道
JavaScript Promise 對比
Js版本
new Promise((resolve, reject) => {
resolve(); // 下一步
})
.then((resolve, reject) => {
reject(); // 下一步
})
.catch(() => {
// 異常處理
})
Lua版本
require("Async").New()
:Ok(function(ok, no)
return ok() -- 下一步
end)
:Ok(function(ok, no)
return no() -- 下一步
end)
:No(function(ok, no)
return no() -- 異常處理
end)
簡單的使用例子
-- 一個簡易的定時器
local Timer = {
mTasks = {}
}
-- 為定時器插入一個任務
function Timer:Insert(tick, func)
table.insert(self.mTasks, { mTick = os.clock() + tick, mFunc = func })
end
-- 更新定時器
function Timer:Update(tick)
local dels = {}
local time = os.clock()
for k, task in pairs(self.mTasks) do
if task.mTick <= time then
table.insert(dels, k)
task.mFunc()
end
end
for i, v in ipairs(dels) do
self.mTasks[v] = nil
end
end
-- 3層嵌套異步調用
Timer:Insert(2, function()
print("clock: \t", os.date("%y-%m-%d %H:%M:%S"))
Timer:Insert(2, function()
print("clock: \t", os.date("%y-%m-%d %H:%M:%S"))
Timer:Insert(2, function()
print("clock: \t", os.date("%y-%m-%d %H:%M:%S"))
end)
end)
end)
-- 通過Async 3層異步調用
require("Async").New()
:Ok(function(ok, no)
Timer:Insert(2, function() print("Async clock: ", os.date("%y-%m-%d %H:%M:%S")) ok() end)
end)
:Ok(function(ok, no)
Timer:Insert(2, function() print("Async clock: ", os.date("%y-%m-%d %H:%M:%S")) ok() end)
end)
:Ok(function(ok, no)
Timer:Insert(2, function() print("Async clock: ", os.date("%y-%m-%d %H:%M:%S")) ok() end)
end)
while true do
Timer:Update(os.clock())
end
**調用結果**
> C:\MyWork\Git\Lua-Async>lua demo.lua
> clock: 19-12-17 21:00:23
> Async clock: 19-12-17 21:00:23
> clock: 19-12-17 21:00:25
> Async clock: 19-12-17 21:00:25
> clock: 19-12-17 21:00:27
> Async clock: 19-12-17 21:00:27
調用結果
C:\MyWork\Git\Lua-Async>lua demo.lua
clock: 19-12-17 21:00:23
Async clock: 19-12-17 21:00:23
clock: 19-12-17 21:00:25
Async clock: 19-12-17 21:00:25
clock: 19-12-17 21:00:27
Async clock: 19-12-17 21:00:27