3.8.3 scheduleOnce bug

多次执行scheduleOnce发现错帧情况

复现代码
for (let i = 0; i < 5; i++) {

        this.scheduleOnce(() => {

            console.log(`${i}  time    ` + new Date().getUTCMilliseconds());

        });

    }

根源应该是在遍历执行timer的时候会删除已经完成的timer,导致定时器错位执行了

for循环是瞬间执行的。
应该是在一个计时器里面递归调用下一个计时器 然后到达边界了再退出

没看懂你在说啥?有执行这段代码么?

就是一帧的时间内创建了5个一样的定时器
image

没理解你所谓的错帧是什么意思,我运行了好几遍,最多时运行时间由1ms的偏差,执行顺序是没有错乱过的,你的意思是有一两个定时器在不同帧被调用了?

你们是用3.x版本运行的吗

3.8.3版本

我3.72版本 从顺序来看 确实很奇怪 你可以跟一下断点 看注册的定时器怎么执行顺序错了

懂了!,但是为什么要依赖定时器顺序啊

原因我都说了呀。。。 for 循环执行后删除timer出问题的

只是我以为是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])

}

2赞

1赞

在这个 PR 修复了:fix logic error when removing an array element in loop by minggo · Pull Request #17215 · cocos/cocos-engine · GitHub

我是2.4.5,真是大乌龙了,哈哈哈


已知会出现 element为null 的情况,具体复现代码还没有,但是这一步已经会出现卡死错误了

跟着引擎组的改,定制一下引擎,他那个是最终解决方案

修改这边的for 循环倒置,之后的删除不会影响前面的定时器,这个pr估计不能解决问题