【鸿蒙生态共建】一文讲清耗时操作对定时器的超时事件影响及解决方案-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利

定时器是研发过程中常用的 API,用于实现不希望代码立即运行,而是等待一段时间后再执行。例如在游戏开发中,可以使用定时器来控制游戏角色的动画播放速度和行动间隔;在数据同步场景中,可利用定时器定期检查并同步本地数据与服务器数据;在界面更新场景中,通过定时器定时刷新界面上的动态信息,如倒计时显示等。

但是,有一种情况下,会block定时器的调度,那就是在同一个函数中,启动了定时器后,在同一个线程执行了一个比较耗时的任务,这时该定时器还没有开始进行调度,会产生block,导致定时的操作没有按预期执行。

本篇内容是《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》这本书第9章内容的延续,是咱这本书读者的福利,在本篇内容中介绍定时器的基本写法及如书写不被block的定时器,欢迎大家一同来深入的了解,甚至可以当作面试题来学习。

对本书感兴趣的同学可以点击以下链接进行购买,或者了解我的班级参加 班级共同学习,点击链接可进入(华为官方活动)

​​​​

《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利博文目录,点击查看

1.定时器的基本写法

下面的示例实现了基本的定时器的写法,100毫秒后执行

复制代码
console.log("俩毛豆 测试定时器 start time");
setTimeout(()=>{
  console.log("俩毛豆 测试定时器 time out");
},100)
console.log("俩毛豆 测试定时器 调用完成");

上面的代码,执行日志如下图所示,可以看出,定时器调用完成的日志先输出,之后约100毫秒定时器时间到。

​2.增加长时任务

下面的示例在同一函数且同一线程内,调用定时器之后,增加一耗时1秒的任务。

复制代码
function longRunningFun() {
  console.log("俩毛豆 测试定时器 模拟耗时1秒开始");
  const startTime = new Date().getTime();
  while (new Date().getTime() - startTime < 1000) {
    // 空循环,模拟1秒耗时
  }
  console.log("俩毛豆 测试定时器 模拟耗时1秒结束");
}

console.log("俩毛豆 测试定时器 start time");
setTimeout(()=>{
  console.log("俩毛豆 测试定时器 time out");
},100)
longRunningFun();
console.log("俩毛豆 测试定时器 调用完成");

可以看出,耗时1秒的操作,影响了定时器的执行。

3.耗时操作使用异步的方式执行

下面的示例,将耗时的操作,使用异步的方式执行

复制代码
function longRunningFun() {
  console.log("俩毛豆 测试定时器 模拟耗时1秒开始");
  const startTime = new Date().getTime();
  while (new Date().getTime() - startTime < 1000) {
    // 空循环,模拟1秒耗时
  }
  console.log("俩毛豆 测试定时器 模拟耗时1秒结束");
}


async function  dolongRunningFunTask(): Promise<string> {
  return new Promise(resolve => {
    longRunningFun();
    resolve("")
  })
}

console.log("俩毛豆 测试定时器 start time");
setTimeout(()=>{
  console.log("俩毛豆 测试定时器 time out");
},100)
dolongRunningFunTask().then(()=>{
  console.log("俩毛豆 测试定时器 耗时任务执行完成 调用方收到事件");
});
console.log("俩毛豆 测试定时器 调用完成");

执行代码log如下图所示,可以看出,因为使用异步执行了耗时操作,定时器的超时时间,会在耗时操作之后(因为在同一个线程,且先被执行),但会在耗时操作执行完成后,立即执行(耗时操作1秒,定时器100毫秒)。

4.解决耗时操作对定时器的影响

从上面的示例代码可以看出,同一线程内的耗时操作会影响定时器的超时事件产生的时间的。如需要解决该问题,需要使用多线程的方式来执行耗时任务。

复制代码
@Concurrent
function longRunningFunConcurrent() {
  console.log("俩毛豆 测试定时器 Concurrent 模拟耗时1秒开始");
  const startTime = new Date().getTime();
  while (new Date().getTime() - startTime < 1000) {
    // 空循环,模拟1秒耗时
  }
  console.log("俩毛豆 测试定时器 Concurrent 模拟耗时1秒结束");
}

async function dolongRunningFunConcurrentTask(): Promise<string> {
  return new Promise(resolve => {
    const task: taskpool.Task = new taskpool.Task(longRunningFunConcurrent);
    taskpool.execute(task).then(() => {
      resolve("")
    })
  })
}
console.log("俩毛豆 测试定时器 start time");
setTimeout(()=>{
  console.log("俩毛豆 测试定时器 time out");
},100)
dolongRunningFunConcurrentTask().then(()=>{
  console.log("俩毛豆 测试定时器 执行完成 调用方收到事件");
});
console.log("俩毛豆 测试定时器 调用完成");

执行log如下图所示,可以看出,定时器超时的事件,并没有被耗时操作影响

5.总结

本文探讨了定时器在鸿蒙应用开发中的使用注意事项。通过示例代码展示了定时器的基本写法,以及同一线程内耗时操作对定时器执行的阻塞影响。文章提出了两种解决方案:一是将耗时操作改为异步执行,二是使用多线程技术(如taskpool)来执行耗时任务。实验结果表明,多线程方式能有效避免耗时操作对定时器的影响。本文内容节选自《精通HarmonyOSNEXT:鸿蒙App开发入门与项目化实战》一书,为读者提供了实用的定时器优化技巧。

对本书感兴趣的同学可以点击以下链接进行购买,或者了解我的班级参加 班级共同学习,点击链接可进入(华为官方活动)

相关推荐
贾伟康40 分钟前
【时光清单|14】HarmonyOS ArkTS 主导航实战:统一页面入口、返回路径和参数校验
harmonyos·arkts·arkui·navigation·路由管理
贾伟康5 小时前
【时光清单|05】HarmonyOS ArkTS 倒计时卡片实战:适配 2x2、2x4 与 4x4 多尺寸
harmonyos·arkts·arkui·服务卡片·formextensionability
小雨青年6 小时前
【HarmonyOS 7 悬浮页签深度实战】07 折叠屏、平板与宽窗口的布局适配
华为·harmonyos
熊猫钓鱼>_>8 小时前
鸿蒙AI Agent新范式:从“对话式辅助”到“工程化代理”的Harness架构实战解析
人工智能·笔记·学习·华为·架构·harmonyos
大锅盖18 小时前
HarmonyOS ArkUI 非遗纹样素材平台设计复盘:朱砂宣纸与鎏金黛蓝的文化守护
华为·harmonyos
2501_919749038 小时前
华为鸿蒙管理学习生活与工作APP—小羊管理
学习·华为·生活·harmonyos·鸿蒙
贾伟康9 小时前
【时光清单|20】HarmonyOS ArkTS AppGallery 发布复查实战:核对包名、版本、设备、素材和离线声明
harmonyos·arkts·agc·appgallery·发布复查
fengkai454510 小时前
三、存储基础知识
华为·云计算·存储
lilian23310 小时前
HarmonyOS 7 新特性(二十三)|hiprofiler + hidumper:跨堆内存分析
华为·harmonyos
嵌入之梦11 小时前
鸿蒙OS IoT设备开发之基础 —— 外设驱动
物联网·华为·harmonyos