这是一个相当复杂的问题,但我会尽可能简单而简洁地解释它......
我正在使用Firebase构建一个基于Web的多用户游戏.我保留了游戏中每一轮的清单.在一轮结束时,每个用户都会看到一个"开始"按钮,当他们准备开始下一轮时,他们会点击该按钮.当至少50%的用户点击"开始"时,该轮开始.
我有一个gameRef
游戏的Firebase参考,一个roundListRef
代表轮次列表的参考,以及一个roundRef
代表当前轮次的参考.
我附加了一个child_added
回调,roundListRef
以便在添加新回合时,它成为每个人的当前回合:
roundListRef.on('child_added', function(childSnapshot, prevChildName) {
roundRef = childSnapshot.ref();
});
Run Code Online (Sandbox Code Playgroud)
我可以跟踪newRoundVotes
和activePlayers
,并从那里很容易计算出50%.如果达到50%,则会添加新一轮,触发每个人的child_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();
});
});
Run Code Online (Sandbox Code Playgroud)
我的问题是,我如何确保只添加一轮新轮次,并且每个人都在同一轮?
例如,假设有10名球员,4名已经投票开始下一轮比赛.如果第6名玩家child_added
在第5名玩家触发事件之前投票,那么第6名玩家也将加入一轮.
问题类似于.set()
vs .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.
}
});
}
Run Code Online (Sandbox Code Playgroud)
这适用于您的方案吗?
归档时间: |
|
查看次数: |
886 次 |
最近记录: |