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

山海万灵 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(): Promise<void> { 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(): Promise<void> { 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 下的附加字段,而不是重新引入多个互斥布尔值。页面继续展示当前图鉴,提示区显示刷新进度;只有缓存与网络内容都不可用时才转入恢复面板。这样既不会遮蔽可阅读内容,也能让失败路径保持明确。

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

相关文章:

  • 计算机 毕业设计之基于spring boot的社区助老志愿者服务中心
  • Android 13 Launcher3深度定制实战:打造16宫格默认文件夹的终极指南
  • DeepSeek LeetCode 3841. 查询树上回文路径 Java实现
  • ViGEmBus虚拟手柄驱动:让Windows游戏控制器兼容性不再烦恼
  • 2026年重庆北碚区找效率高的财税公司 不妨看看辰信财税 - 奔跑123
  • 2026年8月广东驾驶式扫地车品牌**推荐:哪个好? - 工业清洁测评社
  • 郑州空气源地暖服务商哪家专业:【芬尼】管路精工 - 秋山寄远
  • 2026年唐山汽车大灯改装公司哪家好?深改车灯地址电话资料核对|营业时间与到店准备|8月7日更新 - mobible
  • 2026年哈尔滨全品类阀门选购 铸祥建材采购服务推荐 - 奔跑123
  • 郑州芬尼专卖店哪家专业:【芬尼】**认证 - 松梢月冷
  • 2026重庆不锈钢异形廊架/铜雕塑源头厂家怎么选?实用选材避坑选购指南 - mobible
  • 山海万灵 HarmonyOS 文化知识实战(18):Spring Boot 六服务的业务闭环与健康回读
  • 2026 年黄埔诚信的公路波形护栏源头厂家哪家好,路边不起眼的这玩意儿,居然是保命的最后一道防线?-江欧丝网 - 行业推荐官【认证】
  • word怎么转txt?2026年PDF转换工具实测盘点:7款在线转Word、转TXT方案横向看 - 软件小管家
  • 2026年全国盼盼暖气片推荐热门品牌**参考 - 奔跑123
  • GEO系统到底是什么?
  • 2026年8月河北改车灯车灯老化翻新服务门店推荐|唐山深改车灯总部地址、电话与到店准备|2026年8月7日资料更新 - mobible
  • 开题报告AI率检测超标怎么改?它全是论述文字,和正文不是一个改法。
  • 寄大件物流哪家便宜?2026年三大物流渠道对比,省钱攻略全解析 - 快递物流资讯
  • 大模型稀疏注意力和MoE的宽度丢失与多智能体的维度补充
  • 2026河南小型青储机怎么选?豫东青储机源头厂家靠谱选购指南:挑好关键3步不踩坑(更新时间:2026-08-07) - mobible
  • 【2026年百度暑期实习/秋招- 8月6日-算法岗-第三题-报文置换归位】(题目+思路+JavaC++Python解析+在线测试)
  • 2024年深度解析网站建设需要注意哪些核心细节以确保商业成功
  • 企业级Git分支管理策略——从Git Flow到团队协作规范
  • 2026年河北赛那改装车灯雾灯升级改装公司哪家好|电话地址整理 - mobible
  • 2026年霸州老房改造怎么选 推荐几家正规靠谱的改造公司 - 奔跑123
  • 2026郑州大型青储机怎么选?河南青饲料收获机源头生产厂家推荐选购指南(更新时间:2026-08-07) - mobible
  • 2026北京耐候户外玻璃钢雕塑/不锈钢地球雕塑源头厂家推荐:选购指南与实用避坑攻略(更新时间:2026-08-07) - mobible
  • 编程助手募起:写代码这件事正在被重写
  • 2026年深圳铜版纸吊牌源头工厂如何选避坑实用攻略 - 热点品牌推荐