HarmonyOS 7 互动卡片请求超时:为什么不能立刻再提交一次
2026/9/16 9:36:03 网站建设 项目流程

HarmonyOS 7 互动卡片请求超时:为什么不能立刻再提交一次

客户端没有收到回执,不等于服务端没有完成操作。请求超时后立刻换一个操作标识重试,最容易把一次点击变成两次提交。应该先进入结果未知状态,再查询原操作的回执。

适配范围

示例不提供权威回执服务。not_done只有在后端能保证原请求不会再晚到执行时才能使用;否则仍需同key幂等。客户端重启后需要恢复未决操作,不能把内存状态清空就允许再次执行。

案例一

超时但实际成功:收到相同key的done回执后转成功,不产生新操作。

案例二

权威确认尚未执行:允许用原key重试。查询暂时无记录不一定是not_done,存在写入延迟时必须继续保持unknown。

可以运行的实现

export class ActionOutcome { state = 'idle'; key = null; start(key){if(this.state==='pending'||this.state==='unknown')throw Error('unresolved');this.key=key;this.state='pending';} timeout(){if(this.state!=='pending')throw Error('not_pending');this.state='unknown';} reconcile(key,outcome){if(key!==this.key||this.state!=='unknown')return false;if(!['done','not_done'].includes(outcome))throw Error('outcome');this.state=outcome==='done'?'done':'retryable';return true;} }

复现与断言

把实现与以下测试放进同一个example.mjs,执行node example.mjs。断言失败会报错,全部通过正常退出。这些断言已经在本地Node.js执行;它们不代表SDK编译、真机接口调用或性能实测已经通过。

import assert from 'node:assert/strict'; const action=new ActionOutcome();action.start('k1');action.timeout(); assert.throws(()=>action.start('k2'),/unresolved/); assert.equal(action.reconcile('other','done'),false);assert.equal(action.state,'unknown'); assert.equal(action.reconcile('k1','done'),true);assert.equal(action.state,'done'); const retry=new ActionOutcome();retry.start('x');retry.timeout();retry.reconcile('x','not_done');assert.equal(retry.state,'retryable');retry.start('x');assert.equal(retry.state,'pending');

方案取舍

把超时当失败最省事,却把传输状态和业务结果混为一谈。unknown状态虽然让状态机多一条分支,却能保留不确定性。服务端幂等与回执查询比单纯界面防抖更重要。

接入时别漏掉这些边界

示例不提供权威回执服务。not_done只有在后端能保证原请求不会再晚到执行时才能使用;否则仍需同key幂等。客户端重启后需要恢复未决操作,不能把内存状态清空就允许再次执行。

复用时把输入获取与纯逻辑分开:界面、系统事件和服务请求负责取得真实输入,独立模块负责给出判断或保存状态。保留上述两个案例作为回归测试,并对失败原因记录最少必要日志,不记录文件内容、账号凭据或其它敏感数据。升级SDK后重新核对支持设备、接口版本与错误行为,而不是只改目标版本号。

官方资料

HarmonyOS 官方能力入口

示例验证环境为Node.js,验证范围是应用侧逻辑。本文不将示例当作系统接口接入代码;具体接口的支持设备、最低版本和调用方式,以所用SDK对应的官方文档为准。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询