相信大多数小伙伴都使用过组件的 schedule
和 scheduleOnce
函数,主要用来延迟或重复执行指定的函数。
实际上,cc.Component
的 schedule
函数依赖的也是 cc.Scheduler
类,具体使用的也是 cc.director
对象中的 _scheduler
实例。
组件的 schedule
函数在 cc.director._scheduler.schedule
函数之外加了一层封装,「以组件自身作为 target
,这样一来组件内的定时任务就与组件生命周期绑定,当组件被销毁时定时任务也会被移除。」
而 scheduleOnce
函数则是在组件的 schedule
接口之外又加了一层简单的封装,写死只会在指定时间后执行一次。
首先,setTimeout
和 setInterval
函数都是由浏览器或 Node.js 这类 runtime 所提供的接口。
setTimeout
函数用于设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。setInterval
函数用于重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。在浏览器中 setTimeout
和 setInterval
函数的最小延时(间隔)是 4ms。
如果是未激活(处于后台)的标签页(tab),最小延时(间隔)则加长到 1000ms。
假如我在当前标签页设置了一个每 500ms 输出一个 log 的定时器,当我切换到别的标签页之后,那么这个定时器就会变成每 1000ms 才输出一个 log。
setInterval(() => {
console.log(Date.now());
}, 500);
//模拟输出
//标签页在前台
//1644572104517
//1644572105013
//1644572105513
//1644572106016
//切换到其他标签页面后
//1644572107169
//1644572108103
//1644572109330
组件的计时器依赖于引擎的 mainLoop()
和组件自身,如果引擎被暂停,那么组件的计时器也会被暂停,如果组件或组件所在的节点被销毁了,那么计时器也会失效。
setTimeout()
和 setInterval()
都依赖于当前所处的 window
对象,也就是说只要当前浏览器标签页不关闭,setTimeout()
和 setInterval()
都还是会执行的。
当你需要在组件内部定时或重复执行某一函数或操作某个节点,那么可以使用组件的计时器。
💬 让我们想象一个场景:
在当前场景中的某个脚本内使用 setInterval() 来重复移动场景中的某个节点,当我们切换场景后会发生什么?
当定时器再次调用回调尝试移动节点的时候,会无法找到目标节点而报错,因为节点已经跟着之前的场景一起被销毁了,而定时器还在继续执行。
这种情况下使用组件的计时器就不会有这种问题,因为计时器会随着组件的销毁而被清除。
而当我们需要执行一些与游戏场景没有关联的事情的时候,就可以考虑使用 setTimeout()
或 setInterval()
。
当然能用组件计时器的话最好还是用组件计时器
Sign in to post a comment
Comment ( 0 )