多次执行scheduleOnce发现错帧情况
复现代码
for (let i = 0; i < 5; i++) {
this.scheduleOnce(() => {
console.log(`${i} time ` + new Date().getUTCMilliseconds());
});
}
根源应该是在遍历执行timer的时候会删除已经完成的timer,导致定时器错位执行了
多次执行scheduleOnce发现错帧情况
复现代码
for (let i = 0; i < 5; i++) {
this.scheduleOnce(() => {
console.log(`${i} time ` + new Date().getUTCMilliseconds());
});
}
根源应该是在遍历执行timer的时候会删除已经完成的timer,导致定时器错位执行了
for循环是瞬间执行的。
应该是在一个计时器里面递归调用下一个计时器 然后到达边界了再退出
没看懂你在说啥?有执行这段代码么?
就是一帧的时间内创建了5个一样的定时器

没理解你所谓的错帧是什么意思,我运行了好几遍,最多时运行时间由1ms的偏差,执行顺序是没有错乱过的,你的意思是有一两个定时器在不同帧被调用了?
你们是用3.x版本运行的吗
3.8.3版本
我3.72版本 从顺序来看 确实很奇怪 你可以跟一下断点 看注册的定时器怎么执行顺序错了
懂了!,但是为什么要依赖定时器顺序啊
只是我以为是3x版本都出问题,没想到是3.8.3版本的问题,是我描述的不够详细
定位到问题了,两重数组,数组移动下标出错,你现在要解决的这个问题的话,可以重写unscheduleForTimer函数,让他延迟一下
let afterUpdateFuc = () => {
for (let one of cacheList) {
unscheduleForTimer.apply(one[0], one[1])}
cacheList.length =0
}
director.on(Director.EVENT_AFTER_UPDATE, afterUpdateFuc)
let cacheList: any[] = []
//@ts-ignore
let unscheduleForTimer: Function = Scheduler.prototype.unscheduleForTimer
//@ts-ignore
Scheduler.prototype.unscheduleForTimer = function (…args) {
cacheList.push([this, args])
}
在这个 PR 修复了:fix logic error when removing an array element in loop by minggo · Pull Request #17215 · cocos/cocos-engine · GitHub 。
我是2.4.5,真是大乌龙了,哈哈哈
跟着引擎组的改,定制一下引擎,他那个是最终解决方案