阶段、进度与取消

组织运行身份、超时、真实取消与过期结果。

扩展 API v1按当前源码核对
本页目录

把任务描述成状态和阶段#

状态回答“任务现在是什么情况”,阶段回答“正在做哪一步”。不要用按钮是否变灰代替任务状态,也不要用一个无限旋转图标代替所有阶段信息。

状态 进入时做什么 可离开的方向
idle 等待输入和明确开始 preparing / failed
preparing 检查输入、工作区和必要配置 running / failed / cancelled
running 显示当前步骤、实际日志和产出 completed / failed / cancelling
cancelling 阻止新步骤,等待真实停止 cancelled / failed
completed 展示已经核对并保存的成果 新运行
failed / cancelled 保留有效输入、日志和文件 明确重试、继续或新运行

这些状态是组件可采用的内部设计,并不是所有组件已经共同实现的通用任务服务。

给每次运行一个身份#

开始时生成新的 runId。所有异步步骤记录这个身份,返回后先核对它是否仍然有效,再更新界面或调度下一阶段。

javascript
async function runStage(state, runId, stage, work) {
  const current = () => !state.disposed && state.runId === runId;
  if (!current()) return { stale: true };
  state.stage = stage;
  try {
    const value = await work();
    return current() ? { stale: false, value } : { stale: true };
  } catch (error) {
    if (!current()) return { stale: true };
    throw new Error(stage + '失败:' + String(error.message || error));
  }
}

调用者遇到 stale: true 必须结束旧运行,不能继续保存或启动后面的任务。运行身份只能阻止后续回写,不能撤回已经完成的磁盘写入。

防止重复开始#

输入快照、运行身份和占用状态应在第一个异步等待之前建立。运行中重复点击应返回或提示已有任务,不能再启动同一组计算。

对会写同一文件的操作,还需要协调输出目录与文件归属;单纯禁用一个按钮,不能防住其他入口同时覆盖文件。

进度必须有实际依据#

可计量的分批处理可以显示 processed / total。未知总行数、等待模型响应或等待外部程序启动时,显示阶段、活动状态和已知日志即可。

不要把网络字节数假装成整个工作流完成度,也不要让进度先走到 100% 再开始保存。任务完成应对应最终产出已经保存和必要结果已经核对。

超时不是总时长限制#

将检查工作区、连接服务、启动程序和保存文件分别设置边界。错误明确到具体阶段,例如“模型连接超时”“Python 工具未启动”或“保存结果失败”。

Promise.race 可以让等待超时,但本身不会取消后台操作。若采用它,还要处理旧操作晚到及真实停止。正常运行较久的计算不应被一个过短的启动计时器误判。

取消分成两个动作#

  1. 让当前运行身份失效,阻止旧回调继续影响界面。
  2. 对已经开始的网络、工具或进程调用真实取消机制,并确认其状态。

资料统计示例只处理本地批次,递增 runId 后就不会进入下一批。换成 Python、编译或模型请求后,不能照搬这一结论宣称后台已经停止。

错误与重试#

错误记录至少包含阶段和经过脱敏的原因。保留用户输入与已完成产出,不在 finally 中清空所有状态。重试当前阶段、从检查点继续和重新开始应是三个明确选择。

重试要有触发条件和次数边界。路径错误、版本不足和缺少接口不能靠无限重试解决。

下载本页 Markdown