Javascript - Node.js - 防止多次执行函数

时间:2014-03-14 12:51:23

标签: javascript node.js mongodb

我正在用Socket.io创建一个rochambo游戏。玩家将他们的赌注添加到等待名单中,如果玩家有足够的资金,节点会在mondogDB会话中进行检查,然后在将其发送给其他玩家之前创建投注。

我的代码有效但如果我要求快速创建多个投注,节点没有时间在下一个投注到来之前更新mongoDB中的玩家余额,尽管我的等待名单。因此,即使玩家没有足够的钱,玩家也可以下注,我想避免这样做。

我无法找到防止这种情况发生的方法。当然有回调或递归功能,但我没有设法让它工作。

抱歉我的英语不好,我是法国人:)

以下是代码的简化版本:

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();
}});

1 个答案:

答案 0 :(得分:1)

感谢您的回答和帮助,它有效:

   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
    });
});