由于我的理解和SQL背景有限,我不太习惯使用hasChild()和forEach();他们觉得他们属于参考而不是快照。
(我将在其余的讨论中使用hasChild(),但这些概念是可以互换的。)
这是我的推理:
appname/users
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*/
});
});
我不认为基于文档提取appname/users
会产生很大的开销,但如果我只是想确定密钥'Fred'是否存在,这就像是一个难看的代码。< / p>
我希望看到类似的内容:
var users = new Firebase('http://.../appname/users');
users.hasChild('Fred', function(exists[, snapshotOfFred]) {
/* do something here*/
});
使用forEach / hasChild有更好的方法吗?我在这里错过了任何重要的逻辑考虑因素吗?
答案 0 :(得分:12)
您实际上是在第一个代码段的正确轨道上。无论Fred是否已存在,.once()都会使用快照触发回调。所以你可以这样做:
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调整时考虑您的反馈。谢谢!