xLua 中的 util.async_to_sync 方法分析

这个方法的名字,让我产生很大兴趣。
仔细看完后,发现其只能在协程中使用,和C# 的 await关键字一样。

其实就是:在协程中,将 异步回调的方式 变为 同步等待的方式
原理是:异步操作开始后将协程挂起,等异步操作完成调用回调方法后恢复协程。

一、源码分析

--传入一个async方法
local function async_to_sync(async_func, callback_pos)
    --返回一个sync方法
    return function(...)
        --取当前正在运行的协程,若不存在则报错(说明只能在协程中使用!)
        local _co = coroutine.running() or error ('this function must be run in coroutine')
        --定义 结果
        local rets
        --定义 等待标记
        local waiting = false
        --定义 完成时的回调
        local function cb_func(...)
            if waiting then
                --等待后回调的情况
                --从挂起的位置恢复协程,并传递结果
                assert(coroutine.resume(_co, ...))
            else
                --未等待就直接回调的情况,直接设置结果
                rets = {...}
            end
        end
         
        --参数列表 把 “回调” 加入参数列表(默认加入最后)
        local params = {...}
        table.insert(params, callback_pos or (#params + 1), cb_func)

        --调用异步方法,把 “通过同步方法传入的参数” 和 “回调” 全部传给异步方法。
        async_func(unpack(params))

        --如果没有立即返回,则标记为等待并挂起
        if rets == nil then
            waiting = true
            --挂起! "coroutine.yield()" 的返回值为 coroutine.resume 传入的第二个参数
            rets = {coroutine.yield()}
        end
        
        --将结果同步返回
        return unpack(rets)
    end
end

 二、使用层面分析

--异步充值
local function async_recharge(num, cb) 
    print('requst server...')
    --HTTP请求
    http.request(num, function()
        --请求返回,执行异步完成的回调
        cb(true, num) 
    end)
end

--购买的协程
local buy = function() 
    local recharge = async_to_sync(async_recharge)
    --同步使用
    local r1, r2 = recharge(10)
    print('recharge result:', r1, r2)
end

--开始购买的协程
local co = coroutine.create(buy)
assert(coroutine.resume(co))

通常在使用时:
    需要先确定需求,明确自己有一个这样的异步方法:async_recharge(num) ;
    然后 增加一个额外的 完成回调 cb 用来在异步操作完成时调用, 变成 async_recharge(num, cb) ;
    然后 异步转同步 local recharge = async_to_sync(async_recharge) ;
    最后同步方式使用 local r1, r2 = recharge(10);
    注意!这个“完成回调” 的参数(cb的参数),最终会成为同步方法的返回值(r1, r2)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NRatel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值