gpt4 book ai didi

firebase - 为什么我的 Firebase 'child_added' 事件显示无序?

转载 作者:行者123 更新时间:2023-12-04 14:14:52 25 4
gpt4 key购买 nike

我在同一条路径上有 2 个“限制”查询。我首先加载“limit(1)”,然后加载“limit(50)”。

当我加载第二个查询时, child_ added 事件不会按顺序触发。相反,列表中的最后一项(limit(1) 返回的项)首先被触发,然后所有其他项按顺序触发,如下所示:

**Limit 1:**
new Firebase(PATH).limit(1).on('child_added', ...)
Message 5

**Limit 2:**
new Firebase(PATH).limit(50).on('child_added', ...)
Message 5
Message 1
Message 2
Message 3
Message 4

我很困惑为什么在第二个限制操作中首先调用“消息 5”。为什么会发生这种情况,我该如何解决?

最佳答案

我知道这可能看起来很奇怪,但这实际上是预期的行为。

为了保证本地事件可以立即触发而无需先与服务器通信,Firebase 不保证 child_ added 事件将始终按排序顺序调用。

如果这令人困惑,请这样想:如果您根本没有互联网连接,并且您设置了一个限制(50),然后在该引用上调用 push(),您是否希望立即触发一个事件.但是,当您重新连接到服务器时,可能会发现在您推送之前服务器上还有其他项目,然后会在您添加的事件之后触发它们的事件。在您的示例中,问题与本地缓存的数据有关,而不是本地客户端写入的数据,但适用相同的原则。

有关为什么需要以这种方式工作的更详细示例,请想象 2 个客户端 A 和 B:

  • 离线时,客户端 A 调用 push() 并设置一些数据
  • 在线时,客户端 B 添加了一个 child_added 监听器来读取消息
  • 客户端 B 然后调用 push()。它推送的消息会立即在本地触发 child_ added 事件。
  • 客户端 A 重新上线。 Firebase 同步数据,客户端 B 为该数据触发 child_ added 事件。

  • 现在,请注意,即使客户端 A 添加的消息首先出现在列表中(因为它具有较早的时间戳),该事件还是会被第二次触发。

    因此,如您所见,您不能总是依赖事件的顺序来反射(reflect) Firebase 子项的正确排序顺序。

    不过别担心,你仍然可以获得你想要的行为!如果您希望数据按排序顺序而不是事件到达客户端的顺序显示,您有以下几种选择:

    1)(天真的方法)使用“value”事件而不是 child_ added,并在每次使用 forEach 触发时重绘整个项目列表。值事件只会为完整的数据集触发,因此 forEach 将始终按顺序枚举所有事件。但是,这种方法有几个缺点:(1) 值事件在从服务器加载初始状态之前不会触发,因此如果应用程序以“离线模式”启动,则它不会工作,直到网络连接可以已确立的。 (2) 每次更改都会低效地重绘所有内容。

    2)(更好的方法)在 on() 的回调中使用 prevChildName 参数。除了快照之外,当项目按排序顺序放置时,on() 的回调会在查询中传递前一个子项的名称。这允许您以正确的顺序呈现子级,即使事件是无序触发的。见: https://www.firebase.com/docs/javascript/firebase/on.html

    请注意, prevChildName 仅提供查询中的前一个子项,而不是整个 Firebase 位置。因此,查询开头的 child 的 prevChildName 将为 null,即使服务器上有一个 child 在它之前。

    我们的排行榜示例展示了一种操作 DOM 以确保事物以正确顺序呈现的方法。看:
    https://www.firebase.com/tutorial/#example/leaderboard

    关于firebase - 为什么我的 Firebase 'child_added' 事件显示无序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15723278/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com