Javascript – Node.js – 防止多次执行一个函数

我正在用Socket.io创build一个rochambo游戏。 玩家将他们的投注添加到等待列表中,节点在mondogDB会话中检查玩家是否有足够的资金,然后在将其发送给其他玩家之前创build下注。

我的代码可以工作,但是如果我要求快速创build多个投注,节点没有时间在下一个投注到达之前更新mongoDB中的玩家余额,尽pipe等待列表。 所以即使他没有足够的钱,玩家也可以创造赌注,我想避免这种情况。

我找不到防止这种情况发生的方法。 当然有callback或recursionfunction,但我没有设法使其工作。

对不起我可怜的英语,我是法语:)

以下是代码的简化版本:

socket.on('placerunpari', function (screenName, amount, sign) { newBetWaitingList.push({ screenName: screenName, amount: amount, sign: sign }); for (var k in newBetWaitingList) { screenName = newBetWaitingList[k].screenName; amount = newBetWaitingList[k].amount; sign = newBetWaitingList[k].sign; playerModel.findOne({ screenName: screenName }).exec(function (err, player) { if (player != null) { if (checkAmounts(amount) && (sign == "scissors" || sign == "rock" || sign == "paper")) { if (amount <= player.balance) { //DB writing var newBet = new betModel({ screenName: screenName, amount: amount, sign: sign }); newBet.save(function (err, res) { io.sockets.socket(connected[screenName]).emit('mybet', newBet.id, amount, sign); socket.broadcast.emit('newbet', newBet.id, screenName, amount); creatorUpdateBalance(screenName, -amount); }) } else { io.sockets.socket(connected[screenName]).emit('showalert', 'You don\'t have enough money for this bet', 'red'); } } else { console.log('Unauthorized access'); } } }); newBetWaitingList.shift(); }}); 

感谢您的答案和帮助,它的工作原理:

  function CreateBet(task, callback) { screenName = newBetWaitingList[k].screenName; amount = newBetWaitingList[k].amount; sign = newBetWaitingList[k].sign; playerModel.findOne({ screenName: screenName }).exec(function (err, player) { if (player != null) { if (checkAmounts(amount) && (sign == "scissors" || sign == "rock" || sign == "paper")) { if (amount <= player.balance) { //DB writing var newBet = new betModel({ screenName: screenName, amount: amount, sign: sign }); newBet.save(function (err, res) { io.sockets.socket(connected[screenName]).emit('mybet', newBet.id, amount, sign); socket.broadcast.emit('newbet', newBet.id, screenName, amount); creatorUpdateBalance(screenName, -amount, function () { callback(); }); }) } else { io.sockets.socket(connected[screenName]).emit('showalert', 'You don\'t have enough money for this bet', 'red'); callback(); } } else { console.log('Unauthorized access'); callback(); } } }); } var newBetWaitingList = async.queue(CreateBet, 1); socket.on('placerunpari', function (screenName, amount, sign) { newBetWaitingList.push({ screenName: screenName, amount: amount, sign: sign }); });