山海万灵 HarmonyOS 文化知识实战续篇(17):loading、empty、error、retry 统一状态落地

发布时间:2026/11/15 10:54:17

山海万灵 HarmonyOS 文化知识实战续篇(17):loading、empty、error、retry 统一状态落地 知识应用启动时读者看到的并不是一个抽象的请求过程而是图鉴、地域和探索进度能否在合适的时刻出现。山海万灵把加载、内容、空态和恢复动作收敛为同一份状态让首页、图鉴、探索、馆长和档案页共享数据变化的语义。一、四种状态比多个布尔值更稳定单独维护 isLoading、isEmpty 和 hasError 容易产生互相矛盾的组合页面既在加载又提示没有内容或者已经回退到本地资料却仍显示错误。统一 phase 只允许一个主状态生效isLocalFallback 则补充内容的来源信息。export type ShanhaiAppDataPhase LOADING | CONTENT | EMPTY | ERROR; export interface ShanhaiAppLoadState { phase: ShanhaiAppDataPhase; message: string; isLocalFallback: boolean; } export function createShanhaiLoadingState(): ShanhaiAppLoadState { return { phase: LOADING, message: 正在同步山海资料请稍候。, isLocalFallback: false }; }这个模型的关键不在于枚举数量而在于页面只消费一个可信结果。内容可用时进入 CONTENT必要资料为空时进入 EMPTY远端与本地都无法提供内容时才进入 ERROR。每个状态都能映射到明确的视觉反馈和下一步动作。二、启动流程先写入 Loading再决定去向启动阶段先让页面进入 LOADING再由 Bootstrap 结果决定后续状态。内容加载和状态写入在同一处完成避免各个 Feature 页面分别猜测数据是否已经准备好。private async refreshBootstrap(): Promisevoid { this.appLoadState createShanhaiLoadingState(); try { const result await this.appViewModel.loadBootstrapWithStatus(); if (!result.hasRequiredContent) { this.appLoadState createShanhaiEmptyState(); return; } this.applyBootstrap(result.bootstrap); this.appLoadState createShanhaiContentState( result.isLocalFallback ? mock-api 暂不可用正在使用本地内容。 : 内容与图谱已同步。, result.isLocalFallback ); this.refreshAiContext(result.bootstrap.beasts[0].id); } catch (_) { this.appLoadState createShanhaiErrorState(); } }这段顺序同时保留了两层信息页面有没有可展示资料以及资料是否来自本地回退。远端请求暂时失败并不等于读者无法继续阅读只要本地资料完整页面仍进入 CONTENT并用提示语说明当前来源。三、空态和错误态承担不同责任状态出现条件页面反馈用户动作LOADING正在读取启动资料显示进度与同步提示等待CONTENT必要资料已经可用展示图鉴与探索内容继续浏览EMPTY启动结果缺少必要内容说明暂无可展示资料重新同步ERROR没有可用内容可以恢复给出恢复提示重试加载EMPTY 表示结果有效但没有可展示内容ERROR 表示无法获得可用内容。把两者合并会让恢复策略变得模糊空态需要重新同步错误态需要重试加载并且提示文字必须让读者知道接下来能够做什么。四、恢复面板只解释状态不复制业务流程统一面板根据 phase 选择标题和按钮文案。它不直接处理网络细节也不复制 Bootstrap 的读取逻辑所有恢复操作都回到 onRetry从而避免不同页面分别实现一套不一致的重试链路。private title(): string { if (this.state.phase LOADING) { return 正在准备山海资料; } if (this.state.phase EMPTY) { return 暂未发现可展示内容; } return 内容加载失败; } private actionText(): string { return this.state.phase EMPTY ? 重新同步 : 重试加载; }当页面进入恢复模式读者看到的是同一套术语和动作。后续如果增加网络状态、缓存更新或内容版本提示只需要扩展状态层的契约Feature 页面仍然通过同一面板获得一致反馈。五、重试入口必须回到同一条启动链路首页、图鉴、探索和馆长页将同一个 appLoadState 传入各自内容组件并把恢复动作回调到 refreshBootstrap。这样一次点击不会只刷新局部卡片而是重新取得完整 Bootstrap 并再计算跨页面共享的数据。ShanhaiHomePageContent({ beasts: this.beasts, discoveredCount: this.discoveredIds.length, passportCount: this.passportRegionIds.length, syncState: this.appLoadState, onRetrySync: () { this.refreshBootstrap(); } })这种入口收敛还能避免并发状态漂移。刷新前先切到 LOADING成功后一次性应用 Bootstrap失败时统一进入 ERROR页面不会在旧数据与新提示之间留下半更新的组合。六、页面证据观察的是恢复动作下图展示空资料状态下的“重新同步”入口。读者可以看到状态面板没有把空内容伪装成正常图鉴也保留了恢复动作。执行重试后应用会重新走 Bootstrap 流程并用内容状态或新的恢复状态替换当前面板。七、回退内容仍然属于 Content远端服务不可用而本地资料仍然完整时页面不会切换到 ERROR。内容、图谱和探索入口保持可用状态消息提示正在使用本地内容。这个取舍把“数据来源暂时变化”和“读者无法继续阅读”分开处理避免把可用的离线资料隐藏在错误页之后。结果主状态isLocalFallback页面行为远端成功CONTENTfalse显示同步完成后的内容远端失败、本地成功CONTENTtrue继续展示本地资料并提示来源必要资料为空EMPTYfalse显示重新同步没有可用资料ERRORtrue显示重试加载八、验收关注状态切换而不是单个控件验收这条链路时应先观察启动时的同步提示再检查内容可用后的一级页面随后进入空资料状态并点击重新同步确认恢复入口回到完整启动流程。验证重点是 phase、提示语和用户动作是否同步变化而不是只确认某个按钮能够被点击。function applyState(state: ShanhaiAppLoadState): string { if (state.phase LOADING) return 显示加载进度; if (state.phase CONTENT state.isLocalFallback) return 显示本地内容提示; if (state.phase CONTENT) return 显示已同步内容; if (state.phase EMPTY) return 显示重新同步入口; return 显示重试加载入口; }九、状态协议为后续功能保留边界统一状态并不要求每个页面拥有相同布局但要求它们对同一份数据结果作出一致解释。未来增加缓存刷新、内容版本或更细粒度的局部加载时可以在状态层增加字段或子状态而不让五个页面各自引入新的布尔值组合。状态模型、恢复入口和页面回读共同形成了一条可维护的加载链路。HarmonyOS 的状态管理机制可参考 ArkTS 状态管理官方概览。十、把状态更新视为一次完整提交加载链路还要处理快速重复触发。读者连续点击“重新同步”时旧请求可能晚于新请求返回如果旧结果直接覆盖页面就会把已经恢复的内容重新写回空态。状态协调层应为每次启动请求维护递增序号只接受仍然是最新序号的结果。这样 Loading、Content 和恢复面板始终对应同一次请求而不会因返回顺序随机变化。对本地回退也应采用同样的提交原则。先确认远端结果是否仍属于当前请求再决定是否采用本地内容本地内容一旦被选中就连同 isLocalFallback 和提示语一起写入状态。页面只在完整状态对象到达后重新渲染避免列表已经替换而顶部提示仍停留在旧请求的信息。private bootstrapSequence: number 0; private async refreshWithSequence(): Promisevoid { const sequence this.bootstrapSequence; this.appLoadState createShanhaiLoadingState(); try { const result await this.appViewModel.loadBootstrapWithStatus(); if (sequence ! this.bootstrapSequence) return; if (!result.hasRequiredContent) { this.appLoadState createShanhaiEmptyState(); return; } this.applyBootstrap(result.bootstrap); this.appLoadState createShanhaiContentState( result.isLocalFallback ? 正在使用本地内容。 : 内容与图谱已同步。, result.isLocalFallback ); } catch (_) { if (sequence this.bootstrapSequence) this.appLoadState createShanhaiErrorState(); } }这里的序号不是为了给请求编号展示给读者而是为了保护界面事实较早请求只能在它仍然最新时提交结果。网络慢、切换页面或重复点击都不会让旧回调覆盖当前状态。若页面已经卸载协调层也可以在生命周期结束时递增序号使未完成请求自然失效。状态消息同样需要在一次提交中更新。成功内容、空态说明和恢复按钮的文案不应分别异步写入它们属于一个对外可观察的状态快照。读者在任何时刻看到的标题、提示和动作都来自同一个 phase这也是排查加载问题时最容易复现、最容易回读的边界。当后续接入缓存刷新时可以把“正在显示旧内容并刷新”表示为 CONTENT 下的附加字段而不是重新引入多个互斥布尔值。页面继续展示当前图鉴提示区显示刷新进度只有缓存与网络内容都不可用时才转入恢复面板。这样既不会遮蔽可阅读内容也能让失败路径保持明确。
延伸阅读

更多相关文章

2026/11/14 18:19:26

编程助手募起:写代码这件事正在被重写

从代码补全到智能体开发,AI正在重塑软件工程的生产力边界现象篇:当写代码变成「问AI」如果你是2020年入行的程序员,大概率经历过这样的场景:打开IDE,一边写逻辑,一边稍尽切换到搜索引擎查语法、查API。五年…

2026/11/15 13:36:52

国内企业网盘哪家强?我从五个维度做了个深度横评

国内企业网盘哪家强?我从五个维度做了个深度横评 本文横向对比六款国内主流企业网盘产品,从存储架构、检索能力、安全体系、协作能力、AI增强五个维度做深度技术分析。先说结论:国内企业网盘市场已经过了"能用就行"的阶段&#xff…

2026/11/12 22:12:05

国内企业网盘大比拼:六大产品架构深度解析与技术选型指南

国内企业网盘大比拼:六大产品架构深度解析与技术选型指南本文从技术架构视角出发,横向对比国内六款主流企业网盘产品在存储架构、检索引擎、安全体系、智能化能力等核心维度的技术实现差异,为CTO和技术决策者提供选型参考。一、评测背景与方法…

2026/11/15 14:40:00

辛集电工证怎么办理 全国通用电工证怎么考最省心

辛集电工证怎么办理 全国通用电工证怎么考最省心 工地太忙根本没时间复习考试,这是很多电工从业者的真实写照。尤其是在辛集,建筑工地施工节奏快、任务重,很多人都在为电工证的考试和复审头疼。好在现在有全国通用的电工证,不仅能在辛集使用,还能在全国…

2026/11/15 14:40:00

丽江高压电工证怎么考值不值得考 一位外省电工的真实经历

丽江高压电工证怎么考值不值得考 一位外省电工的真实经历 之前考的证在外省能不能转过来?这个问题是很多像你我一样的电工朋友最关心的,尤其是那些在外省工作,想回老家发展或者换城市工作的朋友。今天我就来聊聊我自己的经历,看看…

2026/11/15 14:40:00

遵化市电工证官方回应:怕考不过白交培训费?这些干货必须知道

遵化市电工证官方回应:怕考不过白交培训费?这些干货必须知道 怕考不过白交培训费?遵化市电工证报考前,你必须知道的真相来了。最近有不少学员反馈,报名后担心自己考不过,钱花了,证没拿到,还得重新报名。这事儿其实很多人都在担心,但 官方回应…

2026/11/15 14:35:00

西昌高级电工证多久拿证?学历不高也能考,全流程实操指南

西昌高级电工证多久拿证?学历不高也能考,全流程实操指南 你是不是也担心自己学历不高,西昌高级电工证根本报不了名?别急,我跟你一样,当年也是个初中毕业的工地电工,现在手里拿着高级电工证,月入过万。今天就从报名、培训、考试、发证到年审,一步步带…

2026/11/15 0:02:49

电工证考试口诉怎么准备值不值得考

电工证考试口诉怎么准备值不值得考 实操考试心里没底怕挂科,这是大多数准备考电工证的人心里最真实的感受。尤其是面对【电工证考试口诉】环节,很多人不知道该怎么准备,甚至担心自己说不好就被淘汰。其实,只要掌握方法, 值不值得考…

2026/11/15 0:02:49

桑植县考电工证千万别踩坑!报名全流程教你避坑

桑植县考电工证千万别踩坑!报名全流程教你避坑 你是不是也遇到过这种情况:想考个电工证,但不知道从哪儿下手,怕被中介坑,怕花冤枉钱,更怕考了证还不能用?别急,这正是你该看这篇文章的原因。在桑植县考电工证,确实有很多人被坑过,但只要你知道流程、…

2026/11/15 0:02:49

电工证考试口诉怎么准备值不值得考

电工证考试口诉怎么准备值不值得考 实操考试心里没底怕挂科,这是大多数准备考电工证的人心里最真实的感受。尤其是面对【电工证考试口诉】环节,很多人不知道该怎么准备,甚至担心自己说不好就被淘汰。其实,只要掌握方法, 值不值得考…

2026/11/15 0:02:49

桑植县考电工证千万别踩坑!报名全流程教你避坑

桑植县考电工证千万别踩坑!报名全流程教你避坑 你是不是也遇到过这种情况:想考个电工证,但不知道从哪儿下手,怕被中介坑,怕花冤枉钱,更怕考了证还不能用?别急,这正是你该看这篇文章的原因。在桑植县考电工证,确实有很多人被坑过,但只要你知道流程、…

2026/11/15 4:46:37

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/15 2:06:31

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑