8

以我有限的理解和 SQL 背景,我不太了解 hasChild() 和 forEach(); 的用法。他们觉得他们属于参考而不是快照。

(我将在余下的讨论中使用 hasChild(),但这些概念是可以互换的。)

这是我的推理:

  1. 我有一个需要用户表的 Firebase 路径,比如说appname/users
  2. 我想查看用户(Fred)是否存在
  3. 我得到一个参考:var users = new Firebase('appname/users')

但我无法确定这里是否有孩子。所以这就是我现在所拥有的:

users.child('Fred').once('value', function(snapshot) {
   /** waits around forever if Fred doesn't exist */
});

但这并不完全奏效。因此,现在我必须通过以下方式获取用户的价值(感觉有点违反直觉,因为我对用户不感兴趣):

var users = new Firebase('http://.../appname/users');
users.once('value', function(snapshot) { 
      snapshot.childExists('Fred', function(exists) { 
         /* do something here*/ 
      }); 
   });

根据文档,我不认为通过 fetching 会产生很大的开销appname/users,但是如果我只想确定键“Fred”是否存在,这感觉就像是一段难看的代码。

我想看到类似的东西:

var users = new Firebase('http://.../appname/users');
users.hasChild('Fred', function(exists[, snapshotOfFred]) { 
   /* do something here*/ 
});

有没有更好的方法来使用 forEach/hasChild?我在这里错过了任何重要的逻辑考虑吗?

4

1 回答 1

12

您的第一个代码片段实际上走在了正确的轨道上。.once() 将通过快照触发您的回调,无论 Fred 是否已经存在。所以你可以这样做:

users.child('Fred').once('value', function(snapshot) {
   if (snapshot.val() === null) {
       /* There is no user 'Fred'! */
   } else {
       /* User 'Fred' exists.
   }
});

您的第二个代码片段实际上产生很大的开销,因为 Firebase 会从 Firebase 获取整个“用户”位置,如果您有 1000 个用户,这可能会非常大!所以第一个代码片段绝对是要走的路。

hasChild 和 forEach 位于 DataSnapshot 而不是 Firebase 的原因是它们可以同步。在我们早期的 API 测试中,我们在 Firebase 参考中混合了同步和异步方法,但我们发现这对人们来说是一个重要的绊脚石(如果人们看到 hasChild 方法,他们会期望它返回一个布尔值立即地)。因此,我们创建了 .on() 和 .once() 作为 Firebase 上唯一且唯一的异步回调方法。Firebase 引用上的所有其他内容都是同步的(尽管我们有时会提供可选的异步完成回调),而 DataSnapshot 上的所有内容都是 100% 同步的。

所以我们的目标是让人们更容易理解和使用 Firebase 的异步特性!但也许我们还没有 100% 成功。:-) 在规划未来的 API 调整时,我们会考虑您的反馈。谢谢!

于 2012-07-10T21:15:31.370 回答