【问题标题】:function returns undefined discord.js函数返回未定义的 discord.js
【发布时间】:2021-04-02 01:31:08
【问题描述】:

我正在编写自己的不和谐机器人,并且我有一个应该返回 youtubelink 的函数,但每次我都未定义。这是bot的代码,写在discord.js/node.js中

例如,我在我的不和谐谈话中,我写了“!play allan becker faded”我只在嵌入消息中得到一个未定义,我还尝试控制台记录返回的字符串,但它的 laso undefinedEmbed message

const Discord = require('discord.js')
const fs = require('fs')
const ytdl = require('ytdl-core')
const ffmpeg = require('ffmpeg')
const { debug, Console } = require('console')
const config = JSON.parse(fs.readFileSync('config.json', 'utf8'))
const ytapi3 = config.GoogleApiYT3
const search = require('youtube-search')

var client = new Discord.Client()

//setting status
client.on('ready', () => {
    console.log("Logged in as", client.user.username, "...")
    client.user.setPresence({
        status: config.status,
        activity: {
            name: config.activity,
            type: 'STREAMING',
            url: config.streamingURL
        }
    })
})

//musicbot
client.on('message', async message => {
    if(message.author.bot) return // test if bot has written this message
    if(!message.channel.id == config.botcommandsChannelID) return //test if message is in botcommands channel
    if(!message.content.startsWith(config.prefix)) return // test if prefix is used

    const args = message.content.substring(config.prefix.length).split(" ") // split arguments into args[]-list and cut the prefix out
    const voiceChannel = message.member.voice.channel

    //test if user has permissions to use command
    if(config.UseDJRole == "true") {
        if(message.member.roles.cache.has(config.DJroleID) || message.member.roles.cache.has(config.ModeratorRoleID) || message.member.user.id == config.owner){
        }else{
            return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToUseThisCommand)
        }
    }

    if(!voiceChannel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_404) //testing if user is in voiceChannel

    if(message.content.startsWith(config.prefix + config.PlayCommand)){ //Play-case
        const permission = voiceChannel.permissionsFor(message.client.user)
        if(!permission.has('CONNECT')) sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToJoinVC)
        if(!permission.has('SPEAK')) sendEmbed(message.channel, config.ErrorColor, "Error", config.NoPermissionsToSpeakInVC)
        var vidURL = new String("nothing");

        //get link "vidURL"
        if(args.length >= 2){
            if(ytdl.validateURL(args[1])){
                vidURL = args[1]
            } else{
                args.shift()
                const vidSearchLink = args.join(' ')
                try{
                    vidURL = searchOnYT(vidSearchLink, message.channel, args)
                }catch(error){
                    return console.log(error)
                }
            }
        }else {
            return sendEmbed(message.channel, config.ErrorColor, "Error", config.NoArgs)
        }

        if(client.connection == null){
            voiceChannel.join()
            
            //play
            sendEmbed(message.channel, config.MusicEmbedColorHEX, "Playing", vidURL)
            
        } else{
            if(voiceChannel.id != client.connection.voice.channel.id){
                sendEmbed(message.channel, config.ErrorColor, "Error", config.AllreadyUsed + client.connection.voice.channel.name)
            } else{
                //play
                sendEmbed(message.channel, config.MusicEmbedColorHEX, "Playing", vidURL)
            }
        }

    }else if(message.content.startsWith(config.prefix + config.StopCommand) || message.content.startsWith(config.prefix + config.LeaveCommand)){
        if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
        voiceChannel.leave()
        if(message.member.voice.connection) message.guild.voice.disconnect()
    }else if(message.content.startsWith(config.prefix + config.PauseCommand)){
        if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
        //pause music
    }else if(message.content.startsWith(config.prefix + config.ResumeCommand)){
        if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
        //resume music
    }else if(message.content.startsWith(config.prefix + config.SkipCommand)){
        if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400) //test if you are in one voice channel with the bot
        //skip
    }else if(message.content.startsWith(config.prefix + config.QueueCommand)){
        if(voiceChannel == client.voice.channel) return sendEmbed(message.channel, config.ErrorColor, "Error", config.InvalidVoiceChannel_400)//test if you are in one voice channel with the bot
        //show queue
    }
})

function sendEmbed(_channel, _Color, _Title, _Description, _URL){
    const embedMessage = new Discord.MessageEmbed()
        .setColor(_Color)
        .setTitle(_Title)
        .setDescription(_Description)
        .setURL(_URL);
    _channel.send(embedMessage)

}

function searchOnYT(searchstring, _channel){
    var opts = {
        maxResults: 1,
        key: config.GoogleApiYT3,
        type: 'video'
    }
    search(searchstring, opts, function(err, results) {
        if(err) return console.log(err);
        if(results){
            const r = results[0]
            return new String(r.link)
        }else{
            return sendEmbed(_channel, config.ErrorColor, "Error", NoResultsFound, searchstring)
        }
      })
}

client.login(config.token)

【问题讨论】:

  • 如果在搜索 youtube 视频时发生错误,您将返回 console.log 而不是字符串值(在线:if (err) return console.log(err))。所以我认为正在发生的事情是,一个错误正在发生并且你的searchOnYT() 函数正试图返回一个console.log(它没有输出,因此你会收到undefined 的响应)。当results 未定义时,您可能不想发送“未找到结果”嵌入,而是在定义err 时发送(因此将console.log(err) 替换为searchOnYT()else 语句的内容)。
  • 如果我把结果放在一个console.log中,以防找到一些结果,它给了我正确的东西,我 testet 更多的东西,我注意到它不会等待函数返回,然后继续,这样在函数返回结果未定义之前,我需要searchOnYT()函数等待search(),这样它在返回之前得到结果
  • 我添加了一个答案来解决这个问题。

标签: node.js return discord.js undefined


【解决方案1】:

正如您在评论中提到的,您的 searchOnYT() 函数应该只在获得结果后返回一个值。否则,vidURL 将始终未定义。您可以将Promiseasync/await 结合使用来实现此目的。这是一个示例,只是需要更改的代码部分。

在您的消息处理程序中:

try{
    vidURL = await searchOnYT(vidSearchLink, message.channel, args);
} catch(error){
    return console.log(error)
}

在您的searchOnYT() 函数中:

function searchOnYT(searchstring, _channel){
    var opts = {
        maxResults: 1,
        key: config.GoogleApiYT3,
        type: 'video'
    }

    return new Promise((resolve, reject) => {
        search(searchstring, opts, function(err, results) {
            if(err) reject(err);

            if(results) {
                const r = results[0]
                resolve(new String(r.link))
            }
            else {
                sendEmbed(_channel, config.ErrorColor, "Error", NoResultsFound, searchstring);
                reject("No results found");
            }
          })
    });

}

现在searchOnYT() 返回一个Promise,这确保了函数只会在search() 完成执行后返回一个值。使用回调也可以实现这一点,但 Promise 是一种更简洁的在返回值之前等待的方式(并且 Promise 与 async/await 配合得非常好,幸运的是您的消息处理程序已经使用了 async)。

【讨论】:

  • thx,我也用 promise 和 await 尝试了很多,但它没有用,但现在它工作了
猜你喜欢
  • 2021-05-26
  • 2021-02-27
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 2012-01-15
相关资源
最近更新 更多