添加到列表时是否具有类似Firebase transaction()的功能?
这是一个相当复杂的问题,但我会尽量简单明了地解释它 我正在使用Firebase构建一个多用户、基于web的游戏。我保留着游戏中每一轮的列表。在一轮结束时,每个用户都会看到一个“开始”按钮,当他们准备开始下一轮时,单击该按钮。当至少50%的用户单击“开始”时,该回合开始 我有一个游戏的Firebase参考添加到列表时是否具有类似Firebase transaction()的功能?,firebase,Firebase,这是一个相当复杂的问题,但我会尽量简单明了地解释它 我正在使用Firebase构建一个多用户、基于web的游戏。我保留着游戏中每一轮的列表。在一轮结束时,每个用户都会看到一个“开始”按钮,当他们准备开始下一轮时,单击该按钮。当至少50%的用户单击“开始”时,该回合开始 我有一个游戏的Firebase参考gameRef,一个代表回合列表的参考roundListRef,还有一个代表当前回合的参考roundRef 我在roundListRef中附加了一个child\u added回调,以便在添加新一轮
gameRef
,一个代表回合列表的参考roundListRef
,还有一个代表当前回合的参考roundRef
我在roundListRef
中附加了一个child\u added
回调,以便在添加新一轮时,它将成为每个人的当前一轮:
roundListRef.on('child_added', function(childSnapshot, prevChildName) {
roundRef = childSnapshot.ref();
});
我可以跟踪newroundvoces
和activePlayers
,并从中轻松计算出50%。如果达到50%,将添加新一轮,这将触发每个人的child\u added
事件,新一轮将从那里开始
gameRef.child('newRoundVotes').on('value', function(snapshot) {
var newRoundVotes = snapshot.val();
gameRef.child('activePlayers').once('value', function(snapshot) {
var activePlayers = snapshot.val();
if (newDriveVotes / activePlayers >= 0.5)
addNewRound();
});
});
我的问题是,我如何确保只添加一个新回合,并且每个人都在同一轮
例如,假设有10名球员,4名已经投票开始下一轮比赛。如果第六名玩家在第五名玩家触发其添加的子项之前投票,则第六名玩家也将添加一轮
这个问题类似于.set()
与.transaction()
之间的问题,但据我所知并不完全相同
有人有解决方案吗?我认为如果提前知道轮名,您可以通过事务解决这个问题。例如,如果您只使用/round/0、/round/1、/round/2等 然后您可以编写一些代码,如:
function addNewRound() {
var currentRound = Number(roundRef.name());
var nextRound = currentRound + 1;
// Use a transaction to try to create the next round.
roundRefList.child(nextRound).transaction(function(newRoundValue) {
if (newRoundValue == null) {
// create new round.
return { /* whatever should be stored for the round. */ };
} else {
// somebody else already created it. Do nothing.
}
});
}
这适用于您的场景吗?您可以稍微修改您的想法,并使用圆形计数器作为跟踪并发性的场所
currentRound = 0;
currentRoundRef.on('value', function(snapshot) {
currentRound = snapshot.val();
roundRef = roundListRef.child(currentRound);
});
function addNewRound() {
currentRoundRef.transaction( function(current_value) {
if( current_value !== currentRound ) {
// the round timer has been updated by someone else
return;
}
else {
return currentRound + 1;
}
}, function(success) {
// called after our transaction succeeds or fails
if( success ) {
roundListRef.child(currentRound+1).set(...);
}
});
}
哈那就简单多了。我甚至没有想过你可以对一个还不存在的孩子使用
事务处理。是的,它确实存在-好主意!我一直在使用push(),只是因为它是一个列表,我甚至没有想过要做类似的事情。谢谢