• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

lua函数回调技巧

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

前言

在使用lua 的开发中,有很多异步调用的场景存在,当某个场景中存在多个异步回调操作且该系列操作中每个操作必须依赖上一个操作的完成,这就形成了回调地狱,示例代码:

function f()
    f1(function ()
        f2(function ()
            f3(function ()
                --coding
            end)
        end)
    end)
end

优雅回调

可以想象一个不需要层层嵌套的方式,比如参考js的async.js,而是像瀑布一样,一个个函数依次调用,示例代码:

waterfall({
    function (cb)
        f(cb)
    end,
    function cb)
        f1(cb)
    end,
    function (cb)
        f2(cb)
    end,
    function (cb)
        f3(cb)
    end
}, function ()
    -- coding
end)

要实现以上的效果,需要定义一个内部函数以及一个参数(回调函数)去调用第一个异步函数,当异步函数执行完成以后调用该回调函数,该回调函数内部继续调用下一个异步函数,当所有异步函数都执行完成以后调用最终的回调完成整个过程,这里需要定义一个规范,比如新函数第一个参数为error,如果错误了则终端整个执行过程,实现代码:

function waterfall(tasks, cb)
    local index = 1
    local doNext
    local nextTask = function (...)
        local args = {...}
        local count = select('#', ...)
        args[count + 1] = function (...)
            doNext(...)
        end
        tasks[index](
            table.unpack(args)
        )
    end
    doNext = function (err, ...)
        index = index + 1
        if err or index > #tasks then
            return cb(err, ...)
        end

        nextTask(...)
    end

    nextTask()
end

协程

回调的方式的确有点丑陋,代码量也有点多,如果能像普通调用代码那样,让函数一个个执行,还能达到异步回调的效果,示例代码:

    f()
    f1()
    f2()
    f3()

然而这个效果在当前的lua中是无法实现的,但是合理利用协程的话还是可以接近这个效果的,实现代码:

local function await(fn)
    local run = coroutine.running()
    fn(function()
        coroutine.resume(run)
    end)
    coroutine.yield()
end

function f()
    local co = coroutine.create(function()
        await(f1)
        await(f2)
        await(f3)
    end)
    coroutine.resume(co)
end

用协程去执行第一个异步函数,同时跳回主程序,因为协程跟主程序在同一线程,因此,在协程里调用跟在主程序调用是一样的,当异步调用完成再跳回协程,继续下一个异步调用,如此循环.

结束语

解决函数回调地狱的方式有很多种,比如现在比较流行的Promise\保持代码简短\模块化等等.虽然协程\封装会在一定程度上会增加性能的损耗,但是能更直观的表达代码的业务逻辑,简化开发\维护的成本,始终保持代码简洁才是最重要的.


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
vs如何在C++中调用Lua发布时间:2022-07-22
下一篇:
Cocos2d-x 3.1.1 Lua实例-AccelerometerTest(重力加速计)发布时间:2022-07-22
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap