You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fast-json-patch实现文档版本控制与时间线功能报错如何解决

问题根因
  • 应用补丁的初始基准错误:生成diff补丁时的基准是包含docnumber、notes空数组的初始state,但是应用补丁时使用了空对象{}作为初始值。生成的补丁都是针对/notes/xxx这类路径的修改操作,空对象没有notes属性,而JSON Patch规范(RFC 6902)要求操作路径的父级节点必须存在,fast-json-patch默认严格遵循该规范,不会自动创建不存在的父级路径,直接对/notes/下标路径执行add操作就会抛出赋值错误。
  • 补丁缺失基础字段:因为初始state就包含docnumber字段,所有编辑记录的diff补丁都不会包含新增docnumber的操作,从空对象应用补丁后,最终state也会丢失docnumber字段,不符合预期。
解决方法

1. 替换补丁应用的初始基准

把timetravel函数中初始化newDoc的代码从空对象改成和生成补丁时一致的初始state即可:

function timetravel(doc, editPoint) {
  if (
    doc.parameters.currentedit === editPoint ||
    editPoint > doc.parameters.edits ||
    editPoint < 1
  ) {
    return false;
  }
  const patchesToApply = doc.history.slice(0, editPoint);
  const patches = [].concat.apply([], patchesToApply);
  // 替换原来的 let newDoc = {}
  let newDoc = {
    docnumber: doc.parameters.docnumber,
    notes: []
  };
  newDoc = jsonpatch.applyPatch(newDoc, patches).newDocument;
  doc.state = newDoc;
  doc.parameters.currentedit = editPoint;
  return true;
}

2. 补充初始化参数(可选优化)

在generateDoc的parameters初始化时补充currentedit字段,避免第一次调用timetravel时的undefined判断问题:

const doc = {
  // 新增currentedit默认值,刚生成的文档默认处于最新版本
  parameters: { docnumber, edits, currentedit: edits },
  history: [],
  state: { docnumber, notes: [] },
};
其他方案适配

你之前尝试的两种补丁应用方案逻辑本身没有问题,只要替换正确的初始基准对象都可以正常运行:

  • 方案1把reduce的初始值从{}替换为上述的初始state即可
  • 方案2把newDoc的初始值替换为上述的初始state即可

内容的提问来源于stack exchange,提问作者Dycey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:48:01