【发布时间】:2014-11-05 01:58:13
【问题描述】:
让我们假设这个用例:
Bob 想要评论博客的帖子。
他在写:“我是第一个评论的!”。
几毫秒后,爱丽丝发表了这条评论:“我是第二个!”。
假设每个发布的评论都通过某种 WebSockets 显示给其他用户,而不刷新整个页面。
并假设 cmets 列表应按评论的日期升序排列。
鲍勃应该看到这个:
- 鲍勃:我是第一个
- 爱丽丝:我是第二个
现在假设评论的发布是一个异步过程,这意味着一旦用户点击“发送”,列表就会更新其条目,而不是等待服务器处理:
如果 Bob 的评论在 Alice 的评论之前发送,但在 Alice 的评论之后被服务器处理(存储)了怎么办?
真正的显示(但在 Bob 的屏幕上无效)是:
- 爱丽丝:我是第二个
- 鲍勃:我是第一个
但鲍勃会看到:
- 鲍勃:我是第一个
- 爱丽丝:我是第二个
=> 这没有意义...爱丽丝在鲍勃之后立即在她的键盘上键入。
整个页面的简单刷新将显示:
- 爱丽丝:我是第二个
- 鲍勃:我是第一个
让鲍勃感到困惑!
如果服务器进程是同步的,则不会发生这种情况,这意味着列表将在服务器提交评论后有效显示。
=> Bob 会看到 Alice 的评论出现在他之前,这是一致的。
这种情况下如何处理异步?
【问题讨论】:
-
不要通过
id而是通过create_date列订购cmets,服务器和客户端都是明智的。当通过websocket(或任何异步连接)的新评论到达时,使用create_date将其插入 cmets。 -
当然可以,但我认为您没有很好地解释这个问题。 Bob 的评论不会重新发送给 Bob... => 所以 Bob 仍然会在顶部看到他的评论(直到他刷新整个页面),因为客户端的
create_date总是在 Alice 的前面;即使爱丽丝之前计算过。 -
不,他不会因为服务器将 alices 评论转发给 bob,然后将其插入到 bob 评论之后,因为它的时间戳比 bob 更新。或者您只需将带有评论的客户端创建时间戳发送到服务器,检查其是否现实(以防止人们在几周后发表评论并将时间戳更改为第一个),然后使用客户端时间戳或生成一个新的服务器端.因此,如果它们有效,您实际上是在使用客户端时间戳。
-
我指出 cmets 由 create-date asc 显示,而不是 desc。所以 Bob 的评论在他的客户端的创建日期,总是在没有完全刷新的任何其他 cmets 之前。
-
好的,我已经编辑了我的评论并将“之前”替换为“之后”,因为顺序没有区别。
标签: javascript asynchronous architecture websocket real-time