是否有标准库或工具用于计算和应用差异到JSON文档?基本上我有一堆大文件,我希望通过网络保持同步,我宁愿避免每次我想要同步它们时重新发送它们的整个状态(因为这些变量很多都不会改变).换句话说,我只想传输更改的字段,而不是重新传输整个对象.我认为使用以下一组方法会很方便:
//Start with two distinct objects on the server
// prev represents a copy of the state of the object on the client
// next represents a copy of the state of the object on the server
//
//1. Compute a patch
patch = computePatch(prev, next);
//2. Send patch over the network
//3. Apply the patch on the client
applyPatch(prev, patch);
//Final invariant:
// prev represents an equivalent object to JSON.parse(JSON.stringify(next))
Run Code Online (Sandbox Code Playgroud)
我当然可以自己实现一个,但是有很多边缘情况需要考虑.以下是一些我能想到的简单(虽然有些不尽如人意)的方法,例如:
滚动我自己的JSON修补程序.渐近地,这可能是最好的方法,因为它可以支持JSON文档的所有相关功能,并支持一些专门的方法来执行诸如diffing int,double和string之类的东西(使用相对编码/编辑距离) .然而,JSON有很多特殊情况,我有点怀疑没有经过大量测试就试图这样做,所以我更愿意找到一些已经解决了这个问题的东西让我相信它,并且不必担心由于我的JSON补丁中的错误而出现的网络Heisenbugs
只需使用动态编程直接计算JSON字符串之间的编辑距离.不幸的是,如果客户端和服务器具有不同的JSON实现(即,它们的字段的顺序可以不同地序列化),则这不起作用,并且作为二次时间操作也是相当昂贵的.
使用协议缓冲区.协议缓冲区有一个内置的diff方法,它正是我想要的,它们是一个很好的二进制可序列化的网络友好格式.不幸的是,因为它们也是严格类型的,它们缺少使用JSON的许多优点,例如动态添加和删除字段的能力.现在这是我目前倾向于的方法,但它可能使未来的维护非常可怕,因为我需要不断更新我的每个对象.
做一些非常讨厌的事情,比如为每种类型的对象制作一个自定义协议,并希望我能在两个地方做到正确(是的!).
当然,我真正希望的是这里有一个stackoverflow上的人通过参考一个节省空间的javascript对象不同/修补程序,在生产环境和多个浏览器中经过良好测试,以节省一天.
* …
据我了解,window.innerHeight应该返回没有浏览器镶边(地址栏、导航、标签等)的视口的大小。但在最新版本的iOS13中似乎并非如此。相反,有两个问题:
window.innerHeight值最终太小(大约是底部导航栏的大小),给出了这种可怕的白色屏幕底部的栏。有关更多详细信息,请参阅有关 macrumors 的讨论:https ://forums.macrumors.com/threads/is-this-a-mobile-safari-bug-white-space-appears-at-bottom-after-rotating-iphone.2209551 /window.innerHeight太大并且屏幕底部被切断。即使在打开每个可能的视口标签及其所有排列之后,它似乎也不起作用。我还查看了一些关于如何在 iOS Safari 中处理这个问题的“教程”,到目前为止,我检查过的每个教程都已损坏。
我还尝试了 的所有变体,window.innerHeight结果大致相同:
document.documentElement.clientHeight用CSS的各种置换(使用100vh,100%等等)给出相同的结果。同样适用getBoundingClientRect于各种 div 和 div 元素的组合。window.outerHeight并screen.height给出不带浏览器chrome的全屏大小,一般过大导致溢出。如果您可以猜测顶部和底部浏览器 chrome 的大小,您可以在每个设备的基础上手动捏造它,但这非常脆弱。我正在寻找一种解决方案,它不涉及为每个 iOS 设备和软件配置构建一个巨大的查找表。
我正在尝试为网页游戏制作全屏画布元素,但此问题阻碍了我的发布能力。据我所知,此问题仅存在于 iOS13 中。环顾四周后,我仍然没有找到一个好的解决办法。