如何让函数在下一个时间间隔更新数值?(Discord.js场景)
实现战斗定时数值更新的方案
看起来你想要在battle命令里实现一个「每隔固定时间间隔更新数值」的功能,比如战斗过程中实时刷新玩家/怪物的血量、同步数据库状态。下面结合你的Discord.js Commando代码,给出具体的实现思路和完整代码:
核心实现思路
- 用
setInterval创建定时任务,每隔指定时间执行一次数值更新逻辑 - 每次更新后同步修改数据库中的玩家/怪物数据
- 通过编辑Discord消息实时反馈战斗状态(避免频繁刷屏)
- 战斗结束后必须清除定时任务,防止内存泄漏
完整代码示例
/*jshint esversion: 6*/ const commando = require('discord.js-commando'); const db = require('../../config/db'); module.exports = class Battle extends commando.Command { constructor(client) { super(client, { name: 'battle', aliases: ['fight'], group: 'actions', memberName: 'battle', description: 'What mob to battle.', args: [ { key: 'mob', prompt: 'What mob do you want to attack? Mob ID only!', type: 'integer', }, ], }); } async run(message, { mob }) { try { // 1. 从数据库获取玩家和怪物的初始状态 const [player] = await db.query('SELECT * FROM players WHERE user_id = ?', [message.author.id]); const [mobData] = await db.query('SELECT * FROM mobs WHERE id = ?', [mob]); if (!player || !mobData) { return message.reply(player ? 'Invalid mob ID!' : 'You need to create a character first!'); } // 复制初始数值,避免直接修改数据库查询结果 let currentPlayerHp = player.hp; let currentMobHp = mobData.hp; const attackInterval = 2000; // 每2秒触发一次攻击/数值更新 // 2. 发送初始战斗消息,保存消息对象用于后续编辑 let battleMessage = await message.reply(` **Battle Started!** You vs ${mobData.name} Your HP: ${currentPlayerHp} | Mob HP: ${currentMobHp} `); // 3. 创建定时更新任务 const battleTimer = setInterval(async () => { // 战斗逻辑:玩家和怪物互相攻击,计算伤害 const playerDamage = Math.floor(Math.random() * player.attack) + 1; const mobDamage = Math.floor(Math.random() * mobData.attack) + 1; currentMobHp -= playerDamage; currentPlayerHp -= mobDamage; // 4. 同步更新数据库中的玩家血量 await db.query('UPDATE players SET hp = ? WHERE user_id = ?', [currentPlayerHp, message.author.id]); // 5. 检查战斗是否结束 if (currentPlayerHp <= 0 || currentMobHp <= 0) { clearInterval(battleTimer); // 必须清除定时任务,防止内存泄漏 const battleResult = currentPlayerHp <= 0 ? 'You lost the battle! Better luck next time.' : `You defeated ${mobData.name}! Great job!`; return battleMessage.edit(` **Battle Ended!** ${battleResult} Final Stats: Your HP ${Math.max(currentPlayerHp, 0)} | Mob HP ${Math.max(currentMobHp, 0)} `); } // 6. 更新战斗状态消息 battleMessage.edit(` **Battle in Progress!** You vs ${mobData.name} Your HP: ${currentPlayerHp} | Mob HP: ${currentMobHp} You dealt ${playerDamage} damage! Mob dealt ${mobDamage} damage! `); }, attackInterval); } catch (err) { console.error('Battle command error:', err); message.reply('An error occurred during the battle. Please try again later.'); } } };
关键注意事项
- 定时任务清理:战斗结束(玩家/怪物血量归0)时一定要调用
clearInterval,否则定时任务会一直后台运行,导致内存泄漏 - 异步操作处理:所有数据库查询都要用
await,确保数据同步更新后再执行下一步逻辑 - 消息编辑限制:Discord对消息编辑有频率限制,建议间隔至少1秒以上,避免被平台限制
- 数值安全处理:更新血量时可以用
Math.max()确保数值不会显示为负数,提升用户体验 - 异常捕获:用
try/catch包裹整个逻辑,避免单个战斗出错导致整个命令崩溃
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

