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
相关产品推荐
相关产品推荐

