You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

discord.js音乐机器人dispatcher.on("finish")多次触发清空队列问题

问题根因

你遇到的异常是由finish事件监听器重复绑定导致的:
每次调用playF函数时,无论是否创建了新的播放实例,你都会给当前的server.dispatcher追加一个新的finish事件回调。队列里加N首歌就会调用N次playF,对应绑定N个完全相同的回调函数。当第一首歌播放完成触发finish事件时,所有绑定的回调会同时执行,就会出现你观察到的:触发次数等于队列歌曲总数、队列被快速清空、机器人直接断开连接的问题。

修复方案

核心修复:仅在创建新播放实例时绑定一次事件

把finish事件的绑定逻辑移动到if(!playingMusic)的判断块内部,保证只有新生成dispatcher的时候才会绑定一次事件,不会重复追加监听器。
修复后代码如下:

function playF(connectionF, message){
        console.log("starting the play function ");
        var server = servers[message.guild.id];

        if(!playingMusic){
            console.log("not playing music, running this logic ");
            server.dispatcher = connectionF.play(ytdl(server.queue[0], {filter: "audioonly"}));
            server.queue.shift();
            playingMusic = true;
            // 事件绑定移到此处,仅创建新dispatcher时执行一次
            server.dispatcher.on("finish", () => {
                console.log("running the finish logic "); 
                console.log("heres your queue length in finish " + server.queue.length); 
                playingMusic = false;
                if(server.queue[0]){
                    playF(connectionF, message);
                } else {
                    connectionF.disconnect();
                }
            });
        }
    }

额外优化建议

如果你需要保证绝对不会出现残留监听器,可以在绑定事件前先清理该dispatcher上已有的finish监听器,加上一行server.dispatcher.removeAllListeners("finish")即可。
另外你当前用的全局playingMusic变量会导致多服务器同时使用机器人时状态冲突,建议把播放状态也存储到每个server对象中,不要用全局变量管理。

内容的提问来源于stack exchange,提问作者ElloWorld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 12:48:04