Firebase Web SDK -事务导致on('child_added', function).等待
Firebase Web SDK - Transaction causing on('child_added', func.. to be called
请参见jsbin.com/ceyiqi/edit?html,console,output查看可验证的示例。
我有一个参考监听数据库点
jobs/<key>
/list
其中<key>
为队伍唯一编号
在这个入口点下面是一个作业列表
在这一点上我有一个听众
this.jobsRef.orderByChild('archived')
.equalTo(false)
.on('child_added', function(data) {
我还有一个方法执行以下事务:
ref.transaction(function(post) {
// correct the counter
if(post)
{
// console.log(post);
if(active)
{
// if toggeling on
}
else
{
// if toggeling off
}
}
return post;
})
当调用事务时,child_added
也被再次调用,给我重复的作业。
这是预期行为吗?我是否应该简单地检查项目之前是否已经获得并相应地添加到数组中?还是我做错了什么?
提前感谢您的时间
您在Firebase客户端如何处理事务方面遇到了一个有趣的边缘情况。事务函数运行两次,首先在null
上运行,然后在实际数据上运行。很明显,如果您侦听/jobs上的value
事件,那么您将看到:
- 初始值
- null(当事务在
null
上启动和运行时) - 初始值(当事务在真实数据上再次运行时)
步骤2中的null
值是客户端对当前值的初始猜测。由于客户端没有/jobs的缓存数据(它忽略了/jobs/list的缓存数据),因此它猜测为空。这显然是错误的。但不幸的是,这种情况已经持续了很长时间,所以在当前SDK的主要版本中不太可能改变。
并且由于步骤2中的null
,您将获得child_removed
事件(您现在没有处理),然后在步骤3中您将获得child_added
事件以重新添加它们。
如果你处理了child_removed
事件,你的物品最终不会重复,但它们仍然会消失/重新出现,这可能是不可取的。当前设置中的另一个解决方案是显式地告诉事务不要使用本地估计运行,可以通过将false
作为第三个参数传入来实现:
function transact() {
var path = 'jobs/';
var ref = firebase.database().ref(path);
ref.transaction(function(post) {
return post;
}, function(error, committed, snapshot) {
if (error) {
console.log('Transaction failed abnormally!', error);
} else if (!committed) {
console.log('Transaction aborted.');
} else {
console.log('Transaction completed.');
}
}, false);
}
对不起,我没有更好的解决办法。但正如我所说的:我们不太可能在当前这一代sdk中改变这种行为。
相关文章:
- 在通过child.print()打印之前,我如何等待图像加载到我的新窗口中
- jQuery last child和insetBefore不起作用
- JavaScript Get the child id
- 为什么我不能通过 document.getElementById(“node's_id”).child 选择节点子节点
- jQuery multiple class and nth-child
- Jquery Children's child element
- 在 Twig Child 中添加 CSS 和 JavaScript
- AngularFire 0.5美元移除.错误:Firebase.child失败:第一个参数是无效路径
- Ionic中的Added View显示为纯白色
- 如何多次追加Child(元素).(相同元素)
- removeChild,然后再次添加以前删除的Child以重新加载并清理它
- 为什么Node.removeChild(Old Child)没有't在函数中工作
- node.js没有使用child_process与child进行交互
- Appending Child重置JavaScript上先前附加的元素值
- 创建一个类似datatables.net的表示例,其中包含parent/child和+/-响应按钮
- 使用:nth-child()选择器和.get()方法之间的性能差异
- 节点的怪异行为.removeChild(child)
- jQuery 1.5.1 Sizzle'无法读取属性nodename'child'>'
- 创建 var 并将其插入 jQuery Child Selector(“父>子”)
- 将所有元素包装到 :nth-child