鸿蒙云同步待办清单:30秒轮询改增量同步,别让软删除变“幽灵任务”

举报
yd_274372260 发表于 2026/11/12 12:01:49 2026/11/12
【摘要】 今天在鸿蒙开发实践中心学了案例《云同步待办清单:鸿蒙端云一体实战》,随后在 AI 开发者空间里就两个改造点问了 AI Shell,得到一份可以直接照着改的清单。把学习笔记整理成这篇短文。 一、案例架构一句话案例是一只支持多端云同步的鸿蒙待办清单 App:端侧用 ArkTS/ArkUI 写 Login 与 TodoList 两页;云侧是 8 个 FunctionGraph 云函数(注册登录、任...

今天在鸿蒙开发实践中心学了案例《云同步待办清单:鸿蒙端云一体实战》,随后在 AI 开发者空间里就两个改造点问了 AI Shell,得到一份可以直接照着改的清单。把学习笔记整理成这篇短文。

一、案例架构一句话

案例是一只支持多端云同步的鸿蒙待办清单 App:端侧用 ArkTS/ArkUI 写 Login 与 TodoList 两页;云侧是 8 个 FunctionGraph 云函数(注册登录、任务增删改、同步、建表、诊断);数据落在 RDS for MySQL 的 Todo_DB,users、sessions、tasks 三张表;APIG 专享版是唯一公网入口,所有请求统一带 /todo 前缀转发。端侧每 30 秒调用一次 GET /todo/pull 全量拉取任务,两台设备登录同一账号,改动能在 30 秒内同步一致。

二、想改增量同步,先过“软删除”这一关

全量轮询之所以不会漏删,是因为删除是隐式的:被软删除的任务(is_deleted=1)不在全量返回里,本地全量替换后它自然就没了。

改成按 updated_at 游标增量拉取后,危险就来了:如果软删除只写 SET is_deleted=1,没有刷新 updated_at,这条记录的时间戳还停在创建或上次修改时,WHERE updated_at > cursor 根本捞不到它,客户端永远不知道它被删了,本地会一直留着这条“幽灵任务”。

所以改造要同时做到三件事,缺一不可:

  1. 软删除时顺手刷新 updated_at。delete 云函数里的 SQL 要写成 SET is_deleted=1, updated_at=NOW(),让这次删除“出现在增量查询的视野里”,这是根因修复。
  2. 增量查询不要加 is_deleted=0 过滤,并且把 is_deleted 字段留在返回结果里。客户端按它分流:is_deleted=1 就从本地删除这条,is_deleted=0 就 upsert(有则更新、无则插入)。
  3. 游标推进用本批次数据的最大值,而不是客户端本地时间。服务器写入的时钟和客户端时钟有偏差,游标一旦被推到“未来”,中间的记录就永久漏掉了。批次为空时游标不动,等下一轮再查。

还有两个细节:一是同一毫秒多条记录同时被改,只用 updated_at > cursor 会在下一轮漏掉没取到的几条,办法是游标存 (updated_at, id) 二元组,用 MySQL 的行比较 WHERE (updated_at, id) > (?, ?),批量“清空已完成”一次删几十条时最容易撞上;二是新设备第一次同步没有游标,先做一次全量拉取建立本地基线,拿到最大 updated_at 再切增量。

三、顺手把 Token 从 URL 参数挪到请求头

案例为演示方便,token 走 URL 查询参数传递。它的麻烦不在于“能用”,而在于 URL 会出现在服务器访问日志、浏览器历史、CDN 日志和错误上报里,等于在好几个地方留了明文副本。Authorization 头默认不会被这样记录,是标准做法。

云函数侧要注意三点:FunctionGraph 经 APIG 触发时,请求头字段通常被统一转成小写,取 token 时要做大小写兜底,并剥掉 Bearer 前缀;如果同一套 API 还要给 H5 用,Authorization 不是 CORS“简单请求头”,浏览器会先发 OPTIONS 预检,函数或 APIG 必须在预检响应里返回 Access-Control-Allow-Headers: Authorization,否则 H5 端会突然全报 401;去 APIG 控制台确认集成请求是全量透传请求头,而不是只映射了 body 和 query。

端侧 ArkTS 的 HttpUtil 要注意三点:把所有手动拼 ?token= 的地方删掉,统一在 HttpUtil 的 request 方法里注入 Authorization: Bearer ${token},调用方完全不用碰 token;全局搜一遍 token 在 URL 里的出现点,GET、POST、PUT、DELETE 四个方法如果都拼过就要全改;401 刷新重试时,把“更新 URL”改成“更新请求头”,如果重试是整体重建请求则不用改。

四、最小改动清单(10 项)

数据库层 1 项:软删除 SQL 加 updated_at=NOW()。云函数层 4 项:pull 查询加 updated_at > cursor 且去掉 is_deleted=0 过滤、保留 is_deleted;pull 接收 cursor 与 last_id、返回 next_cursor/next_id;token 从 event.headers[‘authorization’] 取;OPTIONS 预检加 Allow-Headers。端侧 4 项:HttpUtil 统一注入 Bearer 头、删 ?token= 拼接;pull 改传 cursor+last_id 并持久化游标、无游标时走全量;响应按 is_deleted 分流;401 重试改 header。APIG 1 项:确认集成请求全量透传请求头。

建议的顺序是:先改软删除刷新时间戳、pull 查询和本地分流这三处,把“增量+软删除”跑通;再改 token 的取用和注入;最后收尾游标参数、预检与 APIG 配置。

五、参考

  • 案例:鸿蒙开发实践中心《云同步待办清单:鸿蒙端云一体实战》,仓库 harmony-practice-center/todo_list
  • 咨询:华为云 AI 开发者空间(体验版)AI Shell 会话,提问与回复均在 2026 年 11 月 12 日完成
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。