javascript 嵌入异步等待Discord.js的问题-错误无法读取属性Discord.js

c3frrgcw  于 2023-04-19  发布在  Java
关注(0)|答案(1)|浏览(141)

我的Discord Bot中的一个斜杠命令的代码有问题,我使用Mongoose进行DDB管理,一切正常,我从代码中删除了大部分console.log(),以使其在这里更可读,但我检索所有值 没有问题,enter image description here

const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');

const tiny = require("tiny-json-http");
const date = require('date-and-time');

const Calls = require('../calls.js');
const mongoose = require("mongoose");
mongoose.connect('mongodb+srv://****:******@******.ilnqf.mongodb.net/******?retryWrites=true&w=majority');

/* ******************************** */
/* START DEFINING VARIOUS FUNCTIONS */
function priice(price) {
    return Number.parseFloat(price).toFixed(4);
}
function rentaa(renta) {
    return Number.parseFloat(renta).toFixed(2);
}
function roii(roi) {
    return Number.parseFloat(roi).toFixed(2);
}
/* END DEFINING VARIOUS FUNCTIONS */
/* ****************************** */

module.exports = {
    data: new SlashCommandBuilder()
        .setName('stats')
        .setDescription('CHECK YOUR STATS'),
    async execute(interaction) {

        let doc = await Calls.find({ userID: interaction.user.id })
        .then((doc) => { console.log("Result Find :", doc); })
        .catch((err) => { console.log(err); });

        Calls.aggregate([{ $match: { username: interaction.user.username } }, { $group: { _id: { username: interaction.user.username }, rent: { $sum: { $add: ["$roi"] } }, nbrcalls: { $sum: 1 } } }])
            .then((doc) => { console.log('AGGREGATE NBR CALLS: ' + doc[0]['nbrcalls'] + '\nAGGREGATE RENT: ' + doc[0]['rent']);
            Calls.countDocuments({ username: interaction.user.username, win: "1" })
            .then((count) => { console.log('WINS: ' + count);
                Calls.countDocuments({ username: interaction.user.username, loss: "1" })
                .then((count1) => { console.log('LOSSES: ' + count1);
                    let roi = (count / (count + count1)) * 100;
                    console.log('ROI: ' + roi);
                    let renta = doc[0]['rent'] / (count + count1);
                    console.log('RENTA: ' + renta);
                })
                .catch((err) => { console.log(err); })
            })
            .catch((err) => { console.log(err); })
        })
        .catch((err) => { console.log(err); });
        
        const embed = new EmbedBuilder()
            .setDescription('<@' + interaction.user.id + '>, has a total of __' + doc[0]['nbrcalls'] + ' trades__.')
            .setColor(0x18e1ee)
            .setTimestamp(Date.now())
            .addFields(
                { name: "**WINS**", value: count + " ", inline: true },
                { name: "**LOSSES**", value: count1 + " ", inline: true },
                { name: "**WINRATE**", value: parseFloat(roii(roi)) + "%", inline: true },
                { name: "**AVERAGE ROI**", value: parseFloat(rentaa(renta)) + "%", inline: false }
            );
        await interaction.reply({ embeds: [embed] });
        console.log(embed);
    },
};

这是我得到的错误
Error executing stats TypeError: Cannot read properties of undefined (reading '0') at Object.execute (/Users/jeremy/commands/stats.js:50:86)
如果我理解正确的话,我的embed不能访问上面的变量。但是,我不知道如何管理embed,因为如果我挂载它,await.interaction就不工作了。你有我的线索吗?
我用console.log()enter image description here附上了相同代码的屏幕截图
我知道为什么它不工作,但我不知道如何解决这个问题,这是非常恼人的:D
我已经尝试过移动嵌入常量,但如果我向上移动它,它将不起作用。

cclgggtu

cclgggtu1#

问题似乎是你试图在其作用域之外访问doc变量。doc变量是作为find方法调用的结果在execute函数中定义的,只能在同一函数中访问。但是,你试图使用它在该作用域之外构建嵌入。
解决这个问题的一种方法是将构建嵌入的代码移到Calls.aggregate方法的then块中

module.exports = {
  data: new SlashCommandBuilder()
    .setName('stats')
    .setDescription('CHECK YOUR STATS'),
  async execute(interaction) {
    try {
      const doc = await Calls.find({ userID: interaction.user.id });

      Calls.aggregate([{ $match: { username: interaction.user.username } }, { $group: { _id: { username: interaction.user.username }, rent: { $sum: { $add: ["$roi"] } }, nbrcalls: { $sum: 1 } } }])
        .then((docAgg) => {
          const nbrcalls = docAgg[0]['nbrcalls'];
          const rent = docAgg[0]['rent'];
          Calls.countDocuments({ username: interaction.user.username, win: "1" })
            .then((count) => {
              Calls.countDocuments({ username: interaction.user.username, loss: "1" })
                .then((count1) => {
                  const roi = (count / (count + count1)) * 100;
                  const renta = rent / (count + count1);

                  const embed = new EmbedBuilder()
                    .setDescription(`<@${interaction.user.id}>, has a total of __${nbrcalls} trades__.`)
                    .setColor(0x18e1ee)
                    .setTimestamp(Date.now())
                    .addFields(
                      { name: '**WINS**', value: `${count} `, inline: true },
                      { name: '**LOSSES**', value: `${count1} `, inline: true },
                      { name: '**WINRATE**', value: `${roii(roi)}%`, inline: true },
                      { name: '**AVERAGE ROI**', value: `${rentaa(renta)}%`, inline: false }
                    );
                  interaction.reply({ embeds: [embed] });
                })
                .catch((err) => console.log(err));
            })
            .catch((err) => console.log(err));
        })
        .catch((err) => console.log(err));
    } catch (error) {
      console.log(error);
    }
  },
};

在这个修改后的代码中,doc变量从find方法调用中获得,并且可以在Calls.aggregate方法的then块中访问。nbrcalls和rent变量从聚合的结果中获得,count和count 1变量从两个countDocuments方法调用中获得。然后使用这些变量构建嵌入并发送回复。
我还在find方法调用周围添加了一个try-catch块,以处理可能出现的任何错误。
希望这能帮助你解决这个问题!

相关问题