Discord机器人无法添加很多角色...抱怨事件监听器

时间:2019-02-11 05:26:50

标签: node.js events listener discord.js dom-events

我有一个Discord机器人,可以更新我们的Discord上的页首横幅频道。每次将游戏记录到数据库中时,机器人就会获取排行榜数据,然后针对遇到的每个memberId删除所有技能标记(技能越高等于声望更高的标记),然后根据其当前技能添加正确的标记。出于某种原因,连续添加很多成员角色导致该机器人仅从前100名成员中脱颖而出。大约15名成员。我对js很陌生,但我认为每个addRole命令都会触发GuildMemberUpdate事件,而且处理起来太多了。这是我收到的警告消息。其次是大量的角色超时错误(我将添加一个)。

(node:612) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 guildMemberUpdate listeners added. Use emitter.setMaxListeners() to increase limit
    at _addListener (events.js:280:19)
    at Client.addListener (events.js:297:10)
    at Promise (/home/ubuntu/bots/node_modules/discord.js/src/client/rest/RESTMethods.js:511:19)
    at new Promise (<anonymous>)
    at RESTMethods.addMemberRole (/home/ubuntu/bots/node_modules/discord.js/src/client/rest/RESTMethods.js:501:12)
    at GuildMember.addRole (/home/ubuntu/bots/node_modules/discord.js/src/structures/GuildMember.js:453:37)
    at C6Leaderboard.applyTags (/home/ubuntu/bots/modules/leaderboard.js:139:17)
    at C6Leaderboard.createLeaderboard (/home/ubuntu/bots/modules/leaderboard.js:110:18)
    at C6Leaderboard.publishLeaderboard (/home/ubuntu/bots/modules/leaderboard.js:67:29)
    at <anonymous>
Error: Adding the role timed out.
    at timeout.client.setTimeout (/home/ubuntu/bots/node_modules/discord.js/src/client/rest/RESTMethods.js:514:16)
    at Timeout.setTimeout [as _onTimeout] (/home/ubuntu/bots/node_modules/discord.js/src/client/Client.js:433:7)
    at ontimeout (timers.js:475:11)
    at tryOnTimeout (timers.js:310:5)
    at Timer.listOnTimeout (timers.js:270:5)

这是模块代码的要点:

class C6Leaderboard
{
    constructor() {
        util.client.on('ready', () =>
        {
            guild = util.client.guilds.get("291751672106188800");
            this.generate(); //generate an up to date leaderboard
        });
    }

    async generate()
    {
        try
        {
            // Grab data
            this.leaderboard = await util.makeRGRequest('leaderboard.php', {});

            // Publish new Leaderboard
            this.publishLeaderboard();
        }
        catch(err)
        {
            console.log('[leaderboard_err]' + err);
        }
    }

    async publishLeaderboard()
    {
        const channel = util.getChannel(483346000233365526);
        const msg = await channel.fetchMessage(channel.lastMessageID());
        const content_new = this.createLeaderboard();

        if( msg.content != content_new) msg.edit( content_new );
    }

    createLeaderboard(i, max_top)
    {
        //loop through leaderboard data
            //print line of leaderboard message
            this.applyTags(this.leaderboard[i].id, this.leaderboard[i].skill);
    }

    async applytags(id, skill)
    {
         if (!guild)
            return;
        let mem = guild.members.get(id);
        if (!mem)
            return;
        mem.removeRoles(difficulties);
        if (skill < 1500)
            mem.addRole(settler).catch(console.error);
        else if (skill >= 1500 && skill < 1600)
            mem.addRole(chieftain).catch(console.error);
        else if (skill >= 1600 && skill < 1700)
            mem.addRole(warlord).catch(console.error);
        else if (skill >= 1700 && skill < 1800)
            mem.addRole(prince).catch(console.error);
        else if (skill >= 1800 && skill < 1900)
            mem.addRole(king).catch(console.error);
        else if (skill >= 1900 && skill < 2000)
            mem.addRole(emperor).catch(console.error);
        else if (skill >= 2000 && skill < 2100)
            mem.addRole(immortal).catch(console.error);
        else if (skill >= 2100)
            mem.addRole(deity).catch(console.error);
    }
}

1 个答案:

答案 0 :(得分:0)

返回Promise的方法需要使用await调用,并且不能嵌套。

async function applytags(id, skill)
{
     if (!guild)
        return;
    let mem = await guild.members.get(id);
    if (!mem)
        return;
    await mem.removeRoles(difficulties);
    if (skill < 1500)
        await mem.addRole(settler).catch(console.error);
    else if (skill >= 1500 && skill < 1600)
        await mem.addRole(chieftain).catch(console.error);
    else if (skill >= 1600 && skill < 1700)
        await mem.addRole(warlord).catch(console.error);
    else if (skill >= 1700 && skill < 1800)
        await mem.addRole(prince).catch(console.error);
    else if (skill >= 1800 && skill < 1900)
        await mem.addRole(king).catch(console.error);
    else if (skill >= 1900 && skill < 2000)
        await mem.addRole(emperor).catch(console.error);
    else if (skill >= 2000 && skill < 2100)
        await mem.addRole(immortal).catch(console.error);
    else if (skill >= 2100)
        await mem.addRole(deity).catch(console.error);
}
  1. https://anidiots.guide/other-guides/async-await
  2. https://hackernoon.com/javascript-promises-and-why-async-await-wins-the-battle-4fc9d15d509f
  3. https://medium.com/@tkssharma/writing-neat-asynchronous-node-js-code-with-promises-async-await-fa8d8b0bcd7c
  4. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
  5. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function