你的第一段就能看出踩过的坑量,简直共鸣,让我想起了以前的一些经历。多说其实没什么用,经验是自己的,可以少说甚至不说,给自己少点麻烦。同志,新年快乐~~~
+1,haroel同学回答得很好很用心了,不是随便给个一两句话的总结回复。在涉及UI、动画或者其它随时可能会被打断的异步操作时,原生的async/await的弊端就出来了。即使经过封装了,有一定的终止能力,但写起来也可能会比较复杂和容易出错。这时候我会使用generator/yield实现的“协程”来替换,这里的“协程”也只是模拟的startCorutine/stopCorutine,每帧update一次,所以很容易实现终止这样的操作。写法上也跟async/await是一样的,但却不用关心组件是否已经被移除等问题。
前面说啥 async 不能终止,回调也不能终止啊,就像网络请求 ,你发送了难道还能中途取消,还不是在回调的时候加一个判断,判断网络消息回来时对象还在不在,async 写法逻辑是一样的,你自己加个判断,或者加个封装判断对象是否可用就是了。
原来如此, 受教了
非常不喜欢async/await,看见就想给改了。个人习惯吧
写flag确实是可以实现中断,但是async函数里面要写n个flag判断。
C#就有优雅的CancelTask逻辑,他会返回一个Cancel对象,调用就会中断await。
async/await后,在ui上确实要判断await后ui是否被销毁,但同样的,通过callback也照样要判断的。
你举例的时候,说的就是编译后多了 2 层的调用导致的开销来证明 async await 的问题,怎么不是在说调用嵌套越多性能开销越大,那我按你的逻辑,不就是 M 层调用,M 越大性能越差?
我说了半天,是在和你说,你要真注重性能,写汇编就行了,用什么 js 呢?
然后我说的核心点你没理解而已,你关注于 20% 鸡毛蒜皮的点,而没办法证明 async await 的问题。
我们当然是在争论。但是争论得有理有据。你没抓住性能的核心问题,纠结于鸡毛蒜皮的地方,这才是最大的问题。
我们纠结的点在于如何兼顾游戏性能和优雅的编码。
有开发要在技能和动作这种肯定要处理中断的业务中抱怨 async 和 await 不支持中断,而且性能差,我当然不同意这种说法。
这种在确定技术方案的时候当然要考虑调用频率,中断业务,更要兼顾游戏性能的地方,简单的把锅甩给 async/await ,反驳肯定是要反驳的。
我也在反驳啊 ,因为他说无法中断,其实callback本身也无法中断,async/await要处理的,callback也是要处理的,只是用async/await很容易忽略的一点是在await后,如果在ui组件里,还得考虑ui被销毁,这点容易被忽略,实际上callback也是要处理这个问题。
我这么说吧,你 async/await 用完后出问题,这个开发用回调函数也一样出问题。他只是没用回调的方式而已,这不是是 async await 的锅。
你用生成器解决 UI 有生命周期而导致的问题。是一个解决方案,但二者特性不一样,不能比较的。
你说的没错,是这样的
Ui逻辑随便用,gameplay特别是能update解决的,慎重,主要因为不好停止
赞同你的评价。异步会遇到的问题,回调也一定会遇到,相比之下异步更方便
只是编译后的代码体量可能在不同平台不一致
我个人感觉吧,首先promise的出现就是不想代码里出现地狱式回调,还有增强代码的可读性。因为我们在阅读的时候都是从上而下,promise阅读起来就很爽啊,而且他产生的额外内存还不至于导致性能大幅度降低吧。(抛开量来谈都是耍流氓不是)。而且真正导致性能的问题还不是渲染和大量复杂的计算么。promise真的太冤了。
其二吧。。虽然说promise不能终止。。但是我可以封装起来,主动从外部去主动让他主动走catch也算是终止吧。根据参数来决定catch里执行什么逻辑也算是一种变向终止吧。
你的回复好像诗啊
我管它生成的代码和性能咋样,用得爽就行,,
如果项目中有大量async,那本身就是写法的问题吧,要做好封装吆
项目中不要直接用async,可以参考cocos tween的做法,封装一个带Node参数的async。
深有感触,一定要足够理解这个语法才适合用