admin 发表于 2021-5-17 11:50:34

非异步与异步await控件的应用

什么是await控件?
[*]await控件是一个可以调用服务器函数的控件封装
[*]使用此控件后 可以在客户端中调用服务端的函数 并且异步非堵塞 不会卡线程

使用场景:
可以代替 Cli.Send()发送接收封包数据 避免回调地狱
使用await之后 整个数据通讯过程是流程式的 这样可以使我们更好维护与阅读代码

什么是回调地狱:
在我们跟服务端通讯时 需要把一个函数当做参数 用作数据接收返回
当我们需要通讯的次数过多时 就会产生如下的回调地狱
event1(a1,function(ret1)
       event2(ret1,function(ret2)
             event3(ret2,function(ret3)
                  ....
            )
       )
   )
end
而我们希望是 每一个event与服务器通讯之后 可以方便阅读的 如下
ret1 =event1(a1)
ret2 =event2(ret1)
ret3 =event3(ret2)

所以await控件由此诞生 你可以像是在写同步代码的方式来书写异步代码

调用条件:

[*]申明控件为await控件 可以参考一下代码
[*]在event函数中 只有鼠标左键单击双击/右键单击双击会触发 其他如鼠标进入/退出等事件 不会触发异步回调
[*]被调用的服务端函数 必须声明在 unsafe 类下
[*]调用参数均为非安全参数 请自行判断参数的正确性

客户端代码:
function Myrw_init(view)
    if view.IsInit then   
                view.add(new.bmpbutton("change","chajian_btn.bmp"));   
                view.add(new.bmpbutton("await.change","chajian_btn.bmp"));
                return;
    end
      
   -- 非异步回调方式调用服务端函数
   local object = view.find("change");
    object.enable = 1;
    object.xpos = 130;
    object.ypos = 60;
    object.event = function(object,event)
                        if event == Cevent.click then                                                   
                              unsafe.sayhello({"早安,熊弟弟"})
                              -- 使用回调函数接收返回数据 任然无法避免回调地狱
                              unsafe.changeMetamo({104870},function (ret)
                                        Cli.SysMessage(tostring(ret),4,3);               
                              end
                              )      
                        end
               
      end
      
   -- 异步回调方式调用服务端函数
   local object = view.find("await.change");
    object.enable = 1;
    object.xpos = 130;
    object.ypos = 60;
    object.event = function(object,event)
                        if event == Cevent.click then                                                   
                              unsafe.sayhello({"早安,熊弟弟"})
                              
                              -- 当执行到unsafe.changeMetamo这里时 线程会被挂起等待ret返回
                              -- 这个过程是异步的 不会卡游戏线程
                              -- 等待返回后 会自动恢复当时上下线程 这个步骤是自动的 无需关心的
                              local ret = unsafe.changeMetamo({104870});
                              Cli.SysMessage(tostring(ret),4,3);      
                                       
                        end
               
      end
end

服务端代码:
function unsafe.sayhello(player,tbl)            
                NLG.SystemMessage(player,tostring(tbl))                              
end               
                              
function unsafe.changeMetamo(player,tbl)
                local metamoid = tonumber(tbl)
                Char.SetData(player,%对象_形象%,metamoid);
                Char.SetData(player,%对象_原形%,metamoid);
                Char.SetData(player,%对象_原始图档%,metamoid);
                NLG.UpChar(player);                           
                return {'已经变身成['..metamoid.."] 真漂亮,快给大家看看吧!!"}                              
end      




yangxudou 发表于 2022-3-3 18:43:17

谢谢大佬的辛勤努力,多谢分享。
页: [1]
查看完整版本: 非异步与异步await控件的应用