如何实现每10秒自动检查支付状态 解决setInterval无法停止问题
故障原因
- 你当前提供的代码仅执行了1次支付状态查询,没有实现
setInterval定时轮询逻辑,是功能缺失导致的定时检查不生效 - 假设你之前编写的
setInterval逻辑无法终止,核心原因是定时器ID未保存在clearInterval可访问的作用域内,调用清除方法时无法匹配到对应运行的定时任务
修复后完整实现代码
// 可全局声明或者在模块顶层声明Map来存储用户对应的定时器ID,避免重复触发同时方便清除 const userPayIntervals = new Map() client.on('messageCreate', (message) => { if (message.content.startsWith(prefix + 'оплата')) { if (message.channel.name !== 'DM') return message.channel.send("该命令仅可在机器人私信中使用!") const nick = message.content.split(" ").splice(1).join(" ") if (!nick) return message.author.send("请填写您的昵称!") // 避免同一个用户重复发起支付请求导致多个定时器并行 if (userPayIntervals.has(message.author.id)) { clearInterval(userPayIntervals.get(message.author.id)) userPayIntervals.delete(message.author.id) } const params = { publicKey, amount: "1.00" , currency: 'RUB', billId: qiwiApi.generateId(), comment: "月度赞助支付" }; const link = qiwiApi.createPaymentForm(params); const PAYID = new Discord.MessageEmbed() .setAuthor("GUARD QIWI", "https://media.discordapp.net/attachments/899699390082601011/903958418166005760/871755380349341797.png") .setTitle("生成账单") .setDescription(` 支付金额: ${params.amount} ${params.currency} 您的支付ID: ||${params.billId}|| 不要向任何人泄露您的支付ID! 支付链接: [点击跳转](${link})`) message.author.send({ embeds: [PAYID] }) // 启动10秒一次的轮询任务 const checkInterval = setInterval(async () => { try { const data = await qiwiApi.getBillInfo(params.billId) if (data.status.value == "PAID") { // 支付成功立即清除定时器 clearInterval(checkInterval) userPayIntervals.delete(message.author.id) var Rcon = require('rcon'); var conn = new Rcon("**"); conn.on('auth', function() { console.log("Authenticated"); console.log("Sending command: SPONSOR!") conn.send(`**`) }).on('response', function(str) { console.log("Response: " + str); }).on('error', function(err) { console.log("Error: " + err); }).on('end', function() { console.log("Connection closed"); }); conn.connect(); const embed = new Discord.MessageEmbed() .setAuthor("GUARD QIWI", "https://media.discordapp.net/attachments/899699390082601011/903958418166005760/871755380349341797.png") .setDescription(`您的账单已支付成功!`) message.author.send({embeds: [embed]}) return } console.log(`${message.author.id} 尚未支付账单`) } catch (e) { console.log(`${message.author.id} 账单查询失败,未检测到支付记录`) } }, 10 * 1000) // 10秒轮询间隔 // 存储用户对应的定时器ID,方便后续管理 userPayIntervals.set(message.author.id, checkInterval) } })
关键修改点
- 新增
userPayIntervalsMap存储每个用户对应的定时器ID,避免同一用户重复发起支付生成多个并行定时器 - 定时器ID声明在
setInterval同作用域下,支付成功回调内可直接访问到正确ID执行clearInterval - 调整查询逻辑为异步等待写法,避免回调嵌套导致的作用域混乱
- 删除了原代码中会导致进程退出的
process.exit()逻辑,该语句会直接终止机器人进程,是之前可能出现异常退出的隐患
内容的提问来源于stack exchange,提问作者user17292520
相关产品推荐
相关产品推荐

