提问者:小点点

为什么我的回调函数接收到不正确的参数值?


我有一个函数(称为rankCheck),它接受三个参数:

  1. 公会对象(又称不一致服务器)
  2. 用户ID
  3. 回调函数

该函数将从提供的公会中的每个文本通道中获取最后500条消息。然后它将只保留任何以“!rank”开头并由提供的用户ID发送的消息。最后,它将对剩余的消息进行计数,并将整数传递给回调函数。

async function rankChecks(guild, userId = *REMOVED FOR PRIVACY*, callback){
    sumOfRankChecks = 0;       
    guild.channels.cache.each(channel => { //for each text channel, get # of rank checks for userId in last 500 msgs.
        if (channel.type === "text"){
            fetchMessages(channel, 500).then(msgs => {
                let filteredMsgs = msgs.filter(msg => msg.content.startsWith("!rank") && msg.member.user.id == userId);
                sumOfRankChecks = sumOfRankChecks + filteredMsgs.length;
            });
        }
    });
    callback(sumOfRankChecks);
}

由于discord只允许一次获取100个消息,所以我使用这个函数(fetchMessages)来绕过这个限制,方法是发送多个请求,然后将结果合并为一个。

async function fetchMessages(channel, limit) {
    const sum_messages = [];
    let last_id;

    while (true) {
        const options = { limit: 100 };
        if (last_id) {
            options.before = last_id;
        }

        const messages = await channel.messages.fetch(options);
        sum_messages.push(...messages.array());
        last_id = messages.last().id;

        if (messages.size != 100 || sum_messages >= limit) {
            break;
        }
    }

    return sum_messages;
}

当我调用rankCheck函数时,返回值始终为0

        rankChecks(msg.guild, *REMOVED FOR PRIVACY*, function(int){
            console.log(int);
        });

输出:

0

但是,当我添加一个控制台。登录到我的rankCheck函数时:

async function rankChecks(guild, userId = *REMOVED FOR PRIVACY*, callback){
    sumOfRankChecks = 0;       
    guild.channels.cache.each(channel => { //for each text channel, get # of rank checks for userId in last 500 msgs.
        if (channel.type === "text"){
            fetchMessages(channel, 500).then(msgs => {
                let filteredMsgs = msgs.filter(msg => msg.content.startsWith("!rank") && msg.member.user.id == userId);
                sumOfRankChecks = sumOfRankChecks + filteredMsgs.length;
                console.log(sumOfRankChecks) //NEW CONSOLE.LOG!!!!!!!!!!!!!!!
            });
        }
    });
    callback(sumOfRankChecks);
}

输出:

3
5

这是我期望的输出。因为我有2个文本通道在我的服务器,我得到了2个日志。如果您有3个通道,您将获得3个日志等。3个消息来自通道#1,2个消息来自通道#2,因此总共有5个消息。

5应该是传递到回调函数中的整数,但是传递的是0。这是为什么?


共1个答案

匿名用户

您的回调函数甚至在您更改SUMOFrankChecks之前就被调用了。collection#eace(以及map#foreach()和帮派)不能等待承诺来解决,因为它们的构建方式。您的代码也不会等待,因为您没有使用await

不管您可能认为正在发生什么,都会调用guild.channels.eace(),并紧接着调用callback()。这就是你困惑的根源。

有关异步与同步的更多信息,您可以查看我在这里的回答中的解释。您必须使用for循环和await,或者重构代码,使异步/等待语法成为不必要的。

注意:超链接的discord.js文档是针对最近发布的V12的。如果您的discord.js不是最新的,请切换到页面顶部的正确版本以获取准确信息。