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

Discord.js v13创建频道返回undefined?异步等待问题排查

问题:Discord机器人频道创建后返回undefined的异步逻辑问题

我在开发Discord机器人功能:当成员对消息做出反应时,若不存在以其用户名命名的频道则创建该频道,随后在该频道启动测验。频道创建功能正常,但调用setup_channel函数时返回undefined。首次调用setup()时,频道成功创建且已在频道内发送测试用的频道ID,但userchannel变量为undefined;再次调用setup()(此时频道已存在)则一切正常,怀疑是异步等待逻辑存在问题。

相关代码

module.exports.setup_channel = function(guild, user) {

  let userchannel = guild.channels.cache.find(channel => channel.name === user.username);

  if (userchannel) {
    console.log(`${user.username} already exists.`);
    return userchannel;
  }
  else {
    console.log(`Creating ${user.username}.`);
    
    guild.channels.create(user.username, {
      type: 'GUILD_TEXT',
      parent: '1087464585411436615',
      permissionOverwrites: [
        {
          id: guild.id,
          deny: 'VIEW_CHANNEL'
        },
        {
          id: user.id,
          allow: 'VIEW_CHANNEL'
        }
      ]
    })
      .then(async (channel) => {
        await channel.send(`${channel.id}`);
        return channel;
      })
      .catch(console.error);
  }
}


module.exports.setup = async function(client, guildId, user, mode) {

  const guild = client.guilds.cache.get(guildId);

  const userchannel = await this.setup_channel(guild, user);

  console.log(userchannel);

  // …..

控制台输出

Creating marq_andrew.
undefined
marq_andrew already exists.
<ref *2> TextChannel {
  type: 'GUILD_TEXT',
  guild: <ref *1> Guild {

解决方案

核心问题是setup_channel函数在创建频道的分支中没有返回异步操作的Promise,导致await无法获取到频道对象。以下是两种修复方式:

方式1:改用async/await语法

module.exports.setup_channel = async function(guild, user) {
  let userchannel = guild.channels.cache.find(channel => channel.name === user.username);

  if (userchannel) {
    console.log(`${user.username} already exists.`);
    return userchannel;
  } else {
    console.log(`Creating ${user.username}.`);
    try {
      const channel = await guild.channels.create(user.username, {
        type: 'GUILD_TEXT',
        parent: '1087464585411436615',
        permissionOverwrites: [
          {
            id: guild.id,
            deny: 'VIEW_CHANNEL'
          },
          {
            id: user.id,
            allow: 'VIEW_CHANNEL'
          }
        ]
      });
      await channel.send(`${channel.id}`);
      return channel;
    } catch (error) {
      console.error(error);
      throw error; // 抛出错误供调用者处理
    }
  }
}

方式2:直接返回Promise链

module.exports.setup_channel = function(guild, user) {
  let userchannel = guild.channels.cache.find(channel => channel.name === user.username);

  if (userchannel) {
    console.log(`${user.username} already exists.`);
    return Promise.resolve(userchannel);
  } else {
    console.log(`Creating ${user.username}.`);
    // 关键:返回创建频道的Promise链
    return guild.channels.create(user.username, {
      type: 'GUILD_TEXT',
      parent: '1087464585411436615',
      permissionOverwrites: [
        {
          id: guild.id,
          deny: 'VIEW_CHANNEL'
        },
        {
          id: user.id,
          allow: 'VIEW_CHANNEL'
        }
      ]
    })
    .then(async (channel) => {
      await channel.send(`${channel.id}`);
      return channel;
    })
    .catch(console.error);
  }
}

修复说明

原代码中,else分支仅调用了guild.channels.create()但未返回该异步操作的Promise,导致setup_channel函数在这个分支下默认返回undefined,await对undefined无效,因此userchannel为undefined。修改后,setup_channel会返回一个包含频道对象的Promise,await就能正确获取到创建后的频道实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:35:16