確實, 我判斷错了
js的协程Generators是es6的时候出来的,之前是没有的.js的异步底层是宏任务微任务,所以实现Generators也是基于这个事件循环,你把协程代码转成es5代码就可以发现它的实现原理
setTimeout(()=>{},0) 和 this.scheduleOnce(()=>{},0)是不一样的。前者只是把任务立刻放到任务队列里,当前帧的同步代码执行完立刻就执行了,不会等到引擎的下一帧。而后者是会延迟到下一帧执行的。
这个可以实现利用空闲时间完成耗时运算(平常一帧算不完)而不导致卡顿吗?
看你是想怎麽处理, 如果是 在while 或 for里, 使用yield字様就会执行到这就释放运算, 下一帧再继续, 记住函数名前加*号, 不然yield无法生效
控制在一帧时间快到的时候再停止而不是每帧跑一个yield
你这种想方法是不对的
协程的作用在于把一件事分多个帧去处理, 减少一帧的压力
比你原本你要1帧实例100个敌人, 那麽那一帧100%卡, 但是你可以分成每帧实例5个, 20帧实例完
那麽你for循还只需要 for(let i = 0 ;i < 100;++i){ if(i > 0 && i%5==0) yield };
当for执行完结后,协程就销毁了。
一帧差不多13毫秒,第一帧5毫秒渲染完了我让协程跑8毫秒,第二帧10毫秒渲染完了我让协程跑3毫秒。
这样
你协程函数里要执行多久是你自己写了甚麽代码
你可以这様 , yield是分隔线, 一个函数里可以有多个yield
function *f(){
//第一帧内容
let a = 0;
for(let i= 0 ;i < 100;++i){
a+=i;
}
yield //以上是第1帧运行,下面是第二帧
let b = 0;
for(let i= 0 ;i <10;++i){
b+=i;
}
//如果有第三帧要处理的东西再加yield, 否则不写或return
}
协程每次yield的时候检测此时是否为空闲时间,是则next,否则等下一帧渲染后的空闲时间,除非卡顿严重否则只用空闲时间跑协程
问题协程怎麽知道现在是否为空闲? 空闲的定义是甚麽?unity协程有实现你想要的"空闲"时处理吗?协程是主进程里执行的, 别把协程跟线程混淆
private *_test() {
let lastUpdate = cc.director._lastUpdate
let checkNext = function () {
if (performance.now() - lastUpdate > 1000 / cc.game.getFrameRate()) {
console.log("wait for next frame")
lastUpdate = cc.director._lastUpdate
return false
}
}
while (true) {
if (!checkNext()) {
yield;
}
}
}
Coroutine.instance.start(this, this._test);
实现了协程跑无限循环(实际应用为耗时而不需要一帧内完成的方法)而不阻塞游戏循环
我总算理解你想做啥了, 我觉得你这个还不如直接监听
cc.director.on(cc.Director.EVENT_AFTER_UPDATE, this._update, this);
this._update里处理你的一帧耗时计算
在这里要怎么实现呢?这一帧跑太久就达不到满帧率了
为啥要想满帧率呢?看一下引擎源码就知道, 全单线程, 跑完脚本update 再跑render

你用不用协程都不可能满帧率,一秒跌个5帧肉眼也看不出变化, 你只要清楚甚麽东西最会拖慢帧率就行。
另外你看一下CoroutineMgr的源码吧, ta也是基于监听cc.Director.EVENT_AFTER_UPDATE
你那while ture checkNext 也是每帧在跑, 根本没有减轻运算量, 当checkNext return true时还会因为while(true) 阻塞整个主线程
我大致理解你这处理, 就单纯利用时间差值来决定要不要让n增加
所以想你表达是如果主update执行太久, 协程不执行,期望达到满帧率, 但引擎代码都表示了, 在update完成后才跑render函数, 而你的cc.director._lateUpdate值是在mainLoop中未跑update前在函数calculateDeltaTime里更新了, 所以你那协程时间判断只是在判断你脚本的时间, 根本没判断到render时间,所以render 高压力时, 你还是无法满帧率。当然你可以把协程改在cc.Director.EVENT_AFTER_DRAW后执行,但从我的角度来看, 搞了这一堆没有甚麽实制意义的提升