我使用Lua和Corona SDK工作很多,虽然我喜欢它作为一种语言,但我已经意识到我的代码会因为回调调用回调等而变得非常混乱。
我想知道是否有任何设计模式或库(如JavsScript的async.js)有助于减少问题。
典型的例子是使用Corona的过渡调用:
transition.to(obj,{... onComplete=function()
transition.to(obj,{... onComplete=function()
if foo then
transition.to(obj,{... onComplete=function() ... end})
else
transition.to(obj,{... onComplete=function() ... end})
end
end})
end})
我发现代码很快变得非常密集,但通常内部闭包依赖于外部变量。我理解自律是创建干净代码的一个重要因素,但有一个结构强制使用自律是有用的。除了命名闭包之外,有没有人遇到过管理这个问题的有用方法?
答案 0 :(得分:2)
使用协同程序可能会有所帮助:
await = function(f)
return function(...)
local self = coroutine.running()
f(..., {onComplete=function(...)
coroutine.resume(self, ...)
end})
return coroutine.yield()
end
end
await(transition.to)(obj)
await(transition.to)(obj)
if foo then
await(transition.to)(obj)
else
await(transition.to)(obj)
end
或许更一般地说,在评论中解决这个问题:
async_call = function(f)
local self = coroutine.running()
local is_async
local results = nil
local async_continue = function(...)
if coroutine.running() ~= self then
is_async = true
coroutine.resume(self, ...)
else
is_async = false
results = {...}
end
end
f(async_continue)
if is_async then
return coroutine.yield()
else
return unpack(results)
end
end
async_call(function(cont) transition.to(obj, {onComplete=cont}) end)
答案 1 :(得分:0)
一种方法是将回调定义为全局或upvalue,并通过将回调包装在另一个函数中来注入回调所需的upvalues:
function foo(upvalue)
return function(...) -- thats the actual callback
return print(upvalue, ...);
end
end
然后你可以把它作为回调附加,如
transition.to(obj,{... onComplete=foo(somevar)})
然而,附加函数调用对性能的影响很小。另一方面,如果你有多个类似的回调,你可能会想出某种代码重用。