HarmonyOS 7 互动卡片请求超时:为什么不能立刻再提交一次
HarmonyOS 7 互动卡片请求超时为什么不能立刻再提交一次客户端没有收到回执不等于服务端没有完成操作。请求超时后立刻换一个操作标识重试最容易把一次点击变成两次提交。应该先进入结果未知状态再查询原操作的回执。适配范围示例不提供权威回执服务。not_done只有在后端能保证原请求不会再晚到执行时才能使用否则仍需同key幂等。客户端重启后需要恢复未决操作不能把内存状态清空就允许再次执行。案例一超时但实际成功收到相同key的done回执后转成功不产生新操作。案例二权威确认尚未执行允许用原key重试。查询暂时无记录不一定是not_done存在写入延迟时必须继续保持unknown。可以运行的实现export class ActionOutcome { state idle; key null; start(key){if(this.statepending||this.stateunknown)throw Error(unresolved);this.keykey;this.statepending;} timeout(){if(this.state!pending)throw Error(not_pending);this.stateunknown;} reconcile(key,outcome){if(key!this.key||this.state!unknown)return false;if(![done,not_done].includes(outcome))throw Error(outcome);this.stateoutcomedone?done:retryable;return true;} }复现与断言把实现与以下测试放进同一个example.mjs执行node example.mjs。断言失败会报错全部通过正常退出。这些断言已经在本地Node.js执行它们不代表SDK编译、真机接口调用或性能实测已经通过。import assert from node:assert/strict; const actionnew 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 retrynew 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对应的官方文档为准。