【共创季稿事节】秒表应用开发:ArktS 中高精度计时与数组记录


一、引言
秒表(Stopwatch)是日常生活中常用的计时工具,广泛用于运动训练、科学实验、烹饪计时等场景。从技术实现角度看,秒表应用的核心挑战在于:如何实现高精度的计时,以及如何管理和显示圈数记录。
二、需求分析
2.1 功能需求
功能 说明
开始计时 从零开始正向计时
暂停计时 暂停当前计时,保留已计时间
重置清零 将计时归零,同时清空圈数记录
计圈功能 记录当前时间作为一圈的耗时
圈数列表 显示所有记录的圈数
2.2 计时精度设计
普通秒表的精度通常为百分之一秒(0.01s),我们使用"厘秒"(centisecond, 1cs = 0.01s)作为计时单位:
1 秒 = 100 厘秒
使用厘秒作为基本单位而非毫秒,是因为:
百分之一秒的精度对绝大多数场景已经足够
显示格式更符合日常习惯(MM:SS.cs)
三、核心实现
3.1 状态设计
@State elapsed: number = 0; // 经过的厘秒数
@State isRunning: boolean = false;
@State laps: number[] = []; // 圈数记录(也是厘秒)
private timerId: number = -1;
3.2 计时实现
使用 setInterval 每 10ms 触发一次,每次增加 1 厘秒:
this.timerId = setInterval(() => {
this.elapsed++;
}, 10);
为什么是 10ms 而不是 1ms?因为 JavaScript/TypeScript 引擎的单线程模型决定了 setInterval 的实际触发间隔不可能精确到 1ms,10ms 的间隔在实际运行中误差约 ±2ms,对于秒表应用完全可以接受。
3.3 时间格式化
formatTime(cs: number): string {
let minutes = Math.floor(cs / 6000);
let seconds = Math.floor((cs % 6000) / 100);
let centiseconds = cs % 100;
return ${minutes < 10 ? '0' : ''}${minutes}:${ seconds < 10 ? '0' : ''}${seconds}.${ centiseconds < 10 ? '0' : ''}${centiseconds};
}
换算关系:
1 分钟 = 6000 厘秒(60 × 100)
1 秒 = 100 厘秒
3.4 计圈功能
Button(‘⏺ 计圈’)
.onClick(() => {
if (this.isRunning) {
this.laps.push(this.elapsed);
}
})
每点击一次计圈按钮,将当前的 elapsed 值记录到 laps 数组中。由于 @State 的响应式特性,laps 数组的变化会自动更新圈数列表 UI。
四、圈数列表渲染
List() {
ForEach(this.laps, (lap: number, idx: number) => {
ListItem() {
Text(第 ${idx + 1} 圈)
Text(this.formatTime(lap))
}
})
}
使用 ForEach 遍历圈数记录,将每条记录渲染为列表项。
五、生命周期管理
5.1 组件销毁时清除定时器
Button(‘< 返回’)
.onClick(() => {
clearInterval(this.timerId);
router.back();
})
返回主页面时必须清除定时器,这是 ArkTS 开发中极易被忽略的细节。如果定时器未被清除,即使页面已不可见,定时器仍然在后台运行,耗费系统资源。
六、扩展方向
6.1 显示毫秒级精度
如果需要更高精度的计时,可以将计时单位改为毫秒:
this.timerId = setInterval(() => {
this.elapsed++;
}, 1); // 每 1ms 触发
但这会带来两个问题:一是 setInterval 在单线程环境下无法保证 1ms 精度;二是频繁的 UI 刷新会消耗更多资源。通常 10ms(厘秒)精度是性能和体验的最佳平衡点。
6.2 后台计时
当应用进入后台时,鸿蒙系统可能暂停 setInterval 的执行。对于需要精确计时的场景,建议使用系统时间戳(Date.now())来计算实际经过的时间:
startTimer() {
this.startTime = Date.now();
this.timerId = setInterval(() => {
this.elapsed = Math.floor((Date.now() - this.startTime) / 10);
}, 10);
}
这样即使定时器被短暂挂起,恢复后也能准确计算出经过的时间。
七、总结
秒表应用的精髓不在于复杂的业务逻辑,而在于对定时器的精确控制和对数组数据的有效管理。通过这个案例,我们学习了:
setInterval 实现正向计时
厘秒与分钟/秒之间的换算
圈数记录的数组管理
组件生命周期对定时器的影响
秒表背后的"记录-存储-展示"模式,同样适用于运动追踪、实验记录、时间日志等应用场景。
更多推荐



所有评论(0)