当前位置: 首页 > news >正文

【OpenHarmony/HarmonyOs 】限时答题状态机实践:倒计时、暂停、自动提交与实况窗结束态设计

【OpenHarmony/HarmonyOs 】限时答题状态机实践:倒计时、暂停、自动提交与实况窗结束态设计

项目类型:OpenHarmony / HarmonyOS ArkTS 数学学习应用
项目名称:数学视界
对应主题:实况窗、全场景智慧生活、端侧 AI
关键词:ArkTS、倒计时、限时答题、状态机、自动提交、实况窗 ⏱️

一、这篇文章写什么?

之前已经写过答题结果页和题型渲染,这篇只聚焦“答题进行中”的状态管理:倒计时、暂停、自动提交和结束态。

数学视界的QuizPage.ets已经具备限时答题基础:

  • 记录总用时;
  • 每题限时倒计时;
  • 暂停状态;
  • 时间到自动提交;
  • 切题时重置倒计时;
  • 完成后生成结果数据。

这些状态非常适合扩展到“实况窗”思路:把正在进行的挑战展示成系统级持续状态。

二、核心状态:答题过程不是一个布尔值

答题页状态包括:

@StatecurrentIndex: number =0@StateuserAnswers: string[] = []@StatequestionStartTime: number =0@StatetotalTimeSpent: number =0@StateshowAnalysis: boolean = false@StateisSubmitting: boolean = false@StatequestionTimer: number =0@StateisPaused: boolean = false

这些状态共同描述答题过程:

  • 当前第几题;
  • 用户答案;
  • 总用时;
  • 当前题剩余时间;
  • 是否暂停;
  • 是否正在提交;
  • 是否显示解析。

这就是一个小型状态机。

三、启动计时器:总用时和题目倒计时分开

startTimer()中有两个计时器:

startTimer(): void {if(this.timerHandler >=0) { clearInterval(this.timerHandler) }this.timerHandler = setInterval(() => {if(!this.isPaused) {this.totalTimeSpent++ } },1000) }

总用时只关心整个挑战持续了多久。只要没有暂停,就每秒增加。

题目倒计时则和配置有关:

if(cfg.timeLimit !== undefined && cfg.timeLimit >0) {this.questionTimer = cfg.timeLimitthis.questionTimerHandler = setInterval(() => {if(!this.isPaused &&this.questionTimer >0) {this.questionTimer--if(this.questionTimer ===0) {this.autoSubmit() } } },1000) }

这里的设计很清楚:

  • totalTimeSpent是全局;
  • questionTimer是单题;
  • isPaused同时控制两者。

四、暂停:状态机里的关键开关

用户点击关闭按钮时,会进入确认退出状态:

.onClick(() => {this.pulseAnim('close_quiz')this.showConfirmExit =truethis.isPaused =true})

暂停后:

  • 总用时不再增加;
  • 单题倒计时不再减少;
  • 用户可以决定继续或退出。

这比简单clearInterval()更灵活,因为继续答题时不用重新创建整套状态,只要恢复isPaused

五、自动提交:时间到就是一次提交

时间归零后调用:

autoSubmit(): void { this.submitCurrentQuestion() }

提交逻辑:

submitCurrentQuestion(): void {if(this.isSubmitting)returnthis.isSubmitting =truethis.showAnalysis =trueif(this.questionTimerHandler >=0) { clearInterval(this.questionTimerHandler)this.questionTimerHandler = -1} }

这里有两个细节:

  1. isSubmitting防止重复提交;
  2. 提交后清掉单题倒计时,避免解析状态还继续倒计时。

六、下一题:重置单题状态

进入下一题时:

nextQuestion(): void {this.isSubmitting =falsethis.showAnalysis =falseif(this.currentIndex <this.questions.length -1) {this.currentIndex++this.questionStartTime = Date.now()this.userAnswers = [...this.userAnswers]if(cfg.timeLimit !== undefined && cfg.timeLimit >0) {this.questionTimer = cfg.timeLimitthis.questionTimerHandler = setInterval(() => {if(!this.isPaused &&this.questionTimer >0) {this.questionTimer--if(this.questionTimer ===0) {this.autoSubmit() } } },1000) } }else{this.finishChallenge() } }

每题都有自己的倒计时周期。进入下一题后:

  • 隐藏解析;
  • 解除提交中状态;
  • 切换题号;
  • 重新设置倒计时。

七、结束挑战:停止计时并生成结果

完成最后一题后:

finishChallenge(): void {this.stopTimer()constcorrectCount =this.calculateCorrect()consttotalTime =this.totalTimeSpentconstscore = Math.round((correctCount /this.questions.length) *100) }

然后构造结果对象:

const resultData:ChallengeResult={id:Date.now().toString(),config:this.config??{gradeId:'',knowledgeIds:[],questionCount:0},startTime:this.questionStartTime-totalTime*1000,endTime:Date.now(),questions:challengeQuestions,correctCount,totalCount:this.questions.length,totalTime,score,gradeId:this.config?.gradeId??'',knowledgeIds:this.config?.knowledgeIds??[],isCompleted:true, }

这就是从“答题中状态”到“结果页状态”的转换。

八、退出页面时清理计时器

生命周期中调用:

aboutToDisappear(){ this.stopTimer() }

清理函数:

stopTimer(): void {if(this.timerHandler >=0) { clearInterval(this.timerHandler)this.timerHandler = -1}if(this.questionTimerHandler >=0) { clearInterval(this.questionTimerHandler)this.questionTimerHandler = -1} }

这能避免页面退出后计时器还在后台运行。

九、实况窗设计:当前项目可扩展的状态模型

如果后续接入实况窗,可以从现有状态直接构造:

interfaceQuizLiveState {currentIndex:numbertotalCount:numberremainingSeconds:numbertotalTimeSpent:numberstatus:'running'|'paused'|'analysis'|'finished'}

映射关系:

  • isPaused = true:暂停;
  • showAnalysis = true:解析中;
  • questionTimer:剩余秒数;
  • currentIndex + 1:当前题号;
  • finishChallenge():结束态。

实况窗可以展示:

数学挑战 3/10 剩余12秒 当前状态:答题中

结束时可以展示:

挑战完成:80 分 用时 3分20秒

注意:当前项目还没有实际接入系统实况窗,这里是基于现有状态机的扩展设计。

十、总结

这篇文章贴合“实况窗、全场景智慧生活”主题,重点不是泛讲实况窗,而是从项目已有倒计时状态出发。

核心实现包括:

  • ⏱ 用totalTimeSpent记录总用时;
  • ⌛ 用questionTimer记录单题倒计时;
  • ⏸ 用isPaused控制暂停;
  • 🔁 用autoSubmit()处理时间到自动提交;
  • 📖 提交后进入解析状态;
  • 🧹 页面退出时清理计时器;
  • 🚀 可扩展为实况窗运行态、暂停态、解析态和结束态。

限时答题的核心不是倒计时本身,而是状态之间的流转。状态清楚,后续接入实况窗就有了基础。✨

http://www.jsqmd.com/news/1131727/

相关文章:

  • 基于multisim的RC有源滤波器的设计
  • 2026年电销机器人值不值得用?从成本、效果到选型的完整拆解
  • QGC V5.0 gstreamer视频流在安卓端画面卡顿、冻结,硬件解码失败的问题解决方案
  • ClaudeCode本地源码编译、调试、自定义接入大模型实操案例
  • LLaMA 2 / ChatGLM 等5款大模型位置编码对比:RoPE vs 绝对 vs 相对
  • 华为matepad pro运行jupyter
  • 【claude code实践】CLAUDE.md 应该写什么:命令、规范、架构与禁区
  • 2026最新7款AI编程工具学生党平替实测
  • 2026最新8款AI编程助手平替实测 覆盖全场景选型参考
  • 【claude code实践】CLAUDE.md 入门:给 AI 写一份项目说明书
  • 数据视图学习笔记
  • 支持Skill的国内最强AI视频生成工具是谁?Seedance 2.5 全球首发前完整拆解
  • 从零掌握Locust性能测试:Python代码化压测与分布式实战
  • 【OpenHarmony/HarmonyOs 】数学学习报告页:本地统计卡片、正确率与隐私友好学习画像
  • Snowflake OA亲测:两道题20分钟交卷,全靠提前刷过原题
  • FLOPs/MACs/MAdds 概念辨析:3个指标在模型评估中的实际差异与选择
  • 3步搞定FanControl:Windows风扇智能控制的终极指南
  • 终极Android投屏指南:用scrcpy免费实现电脑控制手机
  • Codex 使用额度不够怎么办?Credits、ChatGPT Pro 应该怎么选(2026)
  • YOLOv3 与点云映射:600张图像训练,实现多目标无序抓取 ROI 提取
  • 2026年建筑动画行业观察
  • LTI 系统因果性与稳定性:从 2 个示例到 5 种常见系统类型的判断法则
  • 为什么博容安可SOS功能仅限中国大陆?海外留学生选购防身警报器避坑指南
  • 深度剖析OnmyojiAutoScript:现代化阴阳师自动化框架技术架构演进
  • Matlab【无人机图像】基于联合响应和背景学习实现无人机视觉跟踪附代码
  • 2026最新2款AI编程工具平替之选深度实测
  • AIGC 安全治理的三道防线:输入、输出与运营闭环
  • 2026最新5款AI编程平替实测|适配vibe coding全迭代低成本权威对比
  • 百度网盘秒传脚本终极指南:彻底解决文件分享失效的完整方案
  • Apache多后缀解析漏洞:从原理到实战的Web安全攻防