这是(5年后我知道)正在发生的事情的图形解释(实际上是@osma描述的,但图形解释了):
当您在 GDocs 中加粗一个字符串时,您实际上是将字符串包装到一个容器中,可能是<strong></strong>
它们可能使用任何其他语法。为简单起见,我们只说加粗字符串只需要在单词开头有一个“+”。这样文本“lorem ipsum”就会变成lorem +ipsum
而不是lorem <something>ipsum<something>
1
Alice 和 Bob 都有起始文本“Lorem ipsum”

2
然后鲍勃删除“ipsum”。请注意,他发送给服务器的是变更集retain(6), delete(5)
。变更集本质上是一个补丁,它的结构很可能基于这个库。

3
Alice 将“ipsum”加粗(添加“+”)。请注意,她发送的是变更集retain(6), insert(+), retain(5)

4
两个变更集现在都正在传送到对这些变更集一无所知的服务器。

5
假设最坏的情况:Bob 的包裹先到,然后这个词会被删除。(另一种情况很明显)。

6
当 Alice 的包裹到达时,它只会在文本中添加一个“+”,因为她发送的只是一个 changeset。

7
两个文本都是向客户端广播的变更集。这是第一个。

8
这是第二个。

9
在将这些变更集修补到原始文本中之后,您最终会得到“Lorem +”。这个符号稍后会被一个常见的 HTML 清理过程删除,该过程会消除任何带有格式的标签<tag></tag>
,

要测试此演示,请访问:http: //operational-transformation.github.io/visualization.html。在那里,您可以在发送/接收文本和包裹时玩它们。