1

我经常使用 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})

我发现代码很快变得非常密集,但是内部闭包通常依赖于外部闭包的变量。我很欣赏自律是创建干净代码的一个重要因素,但是拥有一个使用自律强加的​​结构很有用。除了命名闭包之外,还有没有人遇到过一种有用的管理方法?

4

2 回答 2

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) 
于 2013-06-13T20:08:29.107 回答
0

一种方法是将回调定义为全局或上值,并通过将回调包装在另一个函数中来注入回调所需的上值:

function foo(upvalue)
    return function(...) -- thats the actual callback
        return print(upvalue, ...);
    end
end

然后你可以将它附加为回调,如

transition.to(obj,{... onComplete=foo(somevar)})

然而,额外的函数调用将对性能产生一些小的影响。另一方面,如果你有多个类似的回调,你可能会想出某种代码重用。

于 2013-06-13T22:45:04.543 回答