【问题标题】:Fetch Function Not Being Performing In Order | Discord.js获取功能未按顺序执行 |不和谐.js
【发布时间】:2021-05-28 07:35:39
【问题描述】:

总结:

当我运行这个函数时,它会运行一次,跳过我的方法,然后以正确的顺序再次运行。

代码:

function fetch_messages(searched_channel_id){
    client.channels.cache.get(game_log_channel).messages.fetch({ limit: 10 })
        .then(messages => {
            keys = Array.from(messages.keys());
            console.log(keys);
            for ( var i=0; i < keys.length; i++){
                console.log('iterating through messages');
                client.channels.cache.get(game_log_channel).messages.fetch(keys[i])
                    .then(msg => {
                        var msgContent = msg.content;
                        if (msgContent === undefined){
                            msgContent = 'undefined';
                            console.log('undefined message');
                        }
                        else if (msgContent.includes(searched_channel_id)){
                            console.log('channel record found in logs');
                            return [ msg, msgContent, msg.id ];
                        }
                    });
            }
        });
    return 'not found';
};

控制台日志:

问题:

主要问题是它正在发生......有没有办法重写它不会重现错误?

次要问题是它发生的原因。我还没有找到任何关于这种事情发生的文档,我很好奇它的起源。

【问题讨论】:

  • 您将for loop(同步代码)与.fetch(异步)混合。所以它会并行运行所有的`client.channels.cache.get(game_log_channel).messages.fetch(keys[i])`,然后只打印第一个响应的,依此类推。如果你想fetch(1) 然后等待响应然后fetch(2) 使用 await 代替
  • 'not found' 是倒数第二行

标签: javascript node.js for-loop discord.js


【解决方案1】:

想想吧。 fetch() 返回一个承诺。当你调用fetch() 方法时,知道它是异步的,你基本上就是在说

fetch ID 为keys[i] 的消息——不管多长时间 需要 - 但请在获取时(即承诺已解决), 检查获取的消息的内容是否包括 searched_channel_id。干杯。

注意“WHEN”部分。 then() 方法中的任何内容都会在 fetch 被解析后运行(发送 HTTP 请求、接收数据、转换等)。你不知道需要多长时间。

无论如何...当您处于 for 循环中时,现在有点不同了。这次是这样的

我有keys.length ID。 fetch我所有这些消息的ID 将是keys[i]。不管需要多长时间,但请当 获取消息,检查获取的消息内容是否包括 searched_channel_id。我知道你开始取它们的顺序, 我可以理解,完成获取可能需要不同的时间 结果回来了。你不必像我一样一个接一个地去取 真的不在乎你完成获取它们的顺序。

因此,您的代码开始按照 key[0]key[1] 等的顺序解决这些承诺,但如果不等待前面的承诺完成,您将无法控制何时完成。

最后是return 'not found'。就像在说

做我上面提到的所有这些,但是,你知道吗,我真的不在乎 如果您会找到该消息,我们就说它没有找到。我也是 懒得等你完成所有这些。你仍然可以完成工作 我告诉过你,但是呃......

您可以更新您的代码并使用collection#find() 方法来查找给定函数返回真实值的项目:

async function findMessage(channelId) {
  const gameLogChannel = client.channels.cache.get(gameLogChannel);
  const logMessages = await gameLogChannel.messages.fetch({ limit: 10 });

  const foundMessage = logMessages.find((msg) =>
    msg.content.includes(channelId),
  );

  return foundMessage || 'not found';
}

findMessage('98573472597130')
  .then(console.log);

推荐大家观看"What the heck is the event loop anyway? | Philip Roberts | JSConf EU"

【讨论】:

  • 很抱歉回复晚了,非常感谢您详细介绍 - 正如他们所说,教人钓鱼。您的解决方案运行良好。 :)
猜你喜欢
  • 2019-04-13
  • 1970-01-01
  • 2020-08-16
  • 1970-01-01
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多