【发布时间】:2013-04-13 18:40:22
【问题描述】:
每当我在 NodeJS 中定义 Firebase 事务时,我注意到它总是运行三次——前两次使用空数据,最后第三次使用实际数据。这是正常/有意的吗?
例如这段代码:
firebaseOOO.child('ref').transaction(function(data) {
console.log(data);
return data;
});
输出以下内容:
null
null
i1: { a1: true }
我原以为它只打印最后一项。
在cmets中回答一个问题,这里同一个回调:
firebaseOOO.child('ref').transaction(function(data) {
console.log(data);
return data;
}, function(error, committed, snapshot) {
if (error)
console.log('failed');
else if (!committed)
console.log('aborted');
else
console.log('committed');
console.log('fin');
});
产生以下输出:
null
null
i1: { a1: true }
committed
fin
在发布问题之前,我已经阅读了有关事务如何工作的详细信息,因此我尝试将 applyLocally 设置为 false,如下所示:
firebaseOOO.child('ref').transaction(function(data) {
console.log('hit');
return data;
}, function(){}, false);
但它仍然命中 3 次(只是仔细检查)所以我认为这是不同的东西。在交易之前获得“价值”确实按预期“工作”,因为它只命中一次,这与 applyLocally 的设置无关,所以我不确定 applyLocally 是做什么的?这就是我在交易前获取价值的意思:
firebaseOOO.child('ref').once('value', function(data) {
console.log('1');
firebaseOOO.child('ref').transaction(function(data) {
console.log('2');
return data;
});
});
输出:
1
2
@Michael:如何利用这种行为?事务主要是为了让数据使用自己来修改自己——典型的增量++场景。因此,如果我需要在现有值 10 上加 1,并继续使用 11 的结果,则函数命中的前两次我将得到需要处理的错误结果 1,最后是正确的结果第三次命中11。我怎样才能利用这两个最初的 1?另一种情况(也许我不应该为此使用事务,但如果它像我预期的那样工作,它会使代码更清晰)是插入一个值(如果它尚不存在)。如果事务只命中一次,则 null 值将意味着该值不存在,因此您可以在这种情况下将计数器初始化为 1,否则将 1 添加到任何值。对于嘈杂的空值,这是不可能的。
似乎从这一切中得出的结论是更频繁地使用“一次”模式?
一次交易模式:
firebaseOOO.child('ref').once('value', function(data) {
console.log('1');
firebaseOOO.child('ref').transaction(function(data) {
console.log('2');
return data;
});
});
【问题讨论】:
-
这对于事务来说是一个很奇怪的用法。为什么要将其设置回完全相同的值?如果你设置了第二个回调,它会说什么?提交是否成功?有错误吗?
-
嘿加藤,这是证明我的问题的最简单的案例。我的真实代码有更多的逻辑。没有错误信息,最后记录成功。事实上,正如预期的那样,最后只有 1 条提交消息。我更新了我的问题以反映这些结果。