Javascript - Node.js - 防止函数的多次执行
Posted
技术标签:
【中文标题】Javascript - Node.js - 防止函数的多次执行【英文标题】:Javascript - Node.js - Prevent multiple executions of a function 【发布时间】:2014-04-19 18:38:12 【问题描述】:我正在使用 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();
);
【问题讨论】:
您可以将所有投注推入一个队列,然后在计时器(例如 100 毫秒)后处理该队列。因此,您始终可以存储新的赌注,并有时间按到达的顺序处理它们。 ***.com/questions/4700935/… 你可以试试Redis缓存和列表数据结构,用小定时器协调一切会更快。 当您的网站需要在多台机器上运行时,您打算如何处理? 您考虑过使用互斥锁吗?也许这会有所帮助:github.com/jupiter/node-synchronizedasync.queue
和 concurrency = 1
在这里可能会有所帮助。
【参考方案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
);
);
【讨论】:
以上是关于Javascript - Node.js - 防止函数的多次执行的主要内容,如果未能解决你的问题,请参考以下文章