首页 > 解决方案 > 与 discord.js 一起使用时不工作的 clearTimeOut 函数

问题描述

我正在尝试制作一个机器人,在调用 execcmd() 函数后 10 分钟后删除频道('general'),但如果msg是由具有 'idofsomeuser' 的人发送的,那么它应该取消先前的超时并再次启动计时器。但它不起作用。

function execcmd(msg) {
  let ID = msg.author.id
  let chan = msg.guild.channels.cache.find(
    (channel) => channel.name === 'general'
  );
  x = 'idofsomeuser'
  if (ID == x) {
    clearTimeout(x);
    ID = setTimeout(() => {
      chan.delete();
    }, 600000); //10min 
  } else {
    x = setTimeout(() => {
      chan.delete();
    }, 600000);
  }
}
execcmd(msg); //msg is received by client and passed here

标签: javascriptdiscord.js

解决方案


创建一个存储超时变量的闭包函数。这样做使您可以timeout安全地存储它,而无需创建全局变量来存储它。

在回调函数内部首先检查作者的 id 是否匹配。如果是,请清除超时并将其设置为null。然后检查是否timeout等于null并启动计时器。

因此,现在计时器将在第一次调用该函数时启动,并在每次找到具有您要查找的 id 的用户时重新启动。

function createClearChannel(channelName, authorId) {
  let timeout = null;
  const timeoutDuration = 1000 * 60 * 10;

  return function (msg) {
    const isAuthor = authorId === msg.author.id;
    const channel = msg.guild.channels.cache.find(
      channel => channel.name === channelName
    );

    if (isAuthor) {
      clearTimeout(timeout);
      timeout = null;
    }
    
    if (timeout === null) {
      timeout = setTimeout(channel.delete, timoutDuration);
    }
  };
}

要设置它,首先调用createClearChannel函数并传递下面的参数。存储结果execcmd并在消息进入时调用该函数。

(您始终可以省略这些参数,并简单地硬编码用户的频道名称和 ID,但这样做可以使函数更加灵活,因此它也可以用于其他情况。)

重要提示:createClearChannel应该只调用一次。所以不要execcmd在收到每条消息时创建一个新消息,而是每次都使用相同的消息。

const execcmd = createClearChannel('general', 'idofsomeuser');
execcmd(msg);

推荐阅读