简体   繁体   English

使用 Node.js、Mongoose 和 Discord.js 的未定义错误 [无法读取未定义的属性]

[英]Undefined errors using Node.js, Mongoose, and Discord.js [Cannot read property of undefined]

I've been scouring similar problems but haven't seem to have found a solution that quite works on my end.我一直在寻找类似的问题,但似乎还没有找到适合我的解决方案。 So I'm working on a Discord bot that takes data from a MongoDB database and displays said data in the form of a discord embedded message using Mongoose.所以我正在开发一个 Discord 机器人,它从 MongoDB 数据库中获取数据并使用 Mongoose 以不和谐嵌入消息的形式显示所述数据。 For the most part, everything is working fine, however one little section of my code is giving me trouble.在大多数情况下,一切正常,但是我的代码的一小部分给我带来了麻烦。 So I need to import an array of both all available users and the "time" data of each of those users.所以我需要导入一个包含所有可用用户和每个用户的“时间”数据的数组。 Here is the block of code I use to import said data:这是我用来导入所述数据的代码块:

for (i = 0;i < totalObj; i++){
    timeArray[i] = await getData('time', i);
    userArray[i] = await getData('user', i);
}

Now this for loop references a function I made called getData which obtains the data from MongoDB by this method:现在这个 for 循环引用了我创建的一个名为 getData 的函数,它通过这种方法从 MongoDB 获取数据:

async function getData(field, value){
var data;
await stats.find({}, function(err, result){
    if(err){
        result.send(err);
    }else{
        data = result[value];
    }
});

if(field == "user"){
    return data.user;
}else if (field == "time"){
    return data.time;
}else{
    return 0;
}

So that for loop is where my errors currently lie.所以 for 循环是我目前的错误所在。 When I try to run this code and display my data through a discord message, I get this error and the message does not get sent:当我尝试运行此代码并通过不和谐消息显示我的数据时,出现此错误并且消息未发送:

(node:13936) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'time' of undefined (节点:13936)未处理的承诺拒绝警告:类型错误:无法读取未定义的属性“时间”

Now the strange thing is, this error does not happen every time.现在奇怪的是,这个错误并不是每次都发生。 If I continue calling the command that triggers this code from my discord server, it's almost like a 50/50 shot if the command actually shows the message or instead gives this error.如果我继续从我的不和谐服务器调用触发此代码的命令,如果该命令实际显示消息或给出此错误,则几乎就像是 50/50 镜头。 It is very inconsistent.这是非常不一致的。

This error is confounding me, as the undefined part does not make sense to me.这个错误让我感到困惑,因为未定义的部分对我来说没有意义。 The objects that are being searched for in the mongoDB collection are definitely defined, and the for loop never exceeds the number of objects present.在 mongoDB 集合中搜索的对象是明确定义的,for 循环永远不会超过存在的对象数量。 My only conclusion is that I'm doing something wrong with my asynchronous function design.我唯一的结论是我的异步函数设计有问题。 I have tried altering code to use the getData function less often, or to not use awaits or asynchronous design at all, however this leaves my final discord message with several undefined variables and an eventual crash.我曾尝试更改代码以减少使用 getData 函数,或者根本不使用等待或异步设计,但是这使我的最终不和谐消息包含几个未定义的变量并最终导致崩溃。

If anyone has any advice or suggestions, that would be very much appreciated.如果有人有任何意见或建议,将不胜感激。 Just for reference, here is the full function that receives the data, sorts it, and prepares a string to be displayed on the discord server (though the error only seems to occur in the first for loop):仅供参考,这里是接收数据、对其进行排序并准备要在不和谐服务器上显示的字符串的完整函数(尽管错误似乎只发生在第一个 for 循环中):

async function buildString(){
var string = "";
var totalObj;
var timeArray = [];
var userArray = [];
var stopSort = false;

await stats.find({}, function(err, result){
    if(err){
        result.send(err);
    }else{
        totalObj = result.length;
    }
});

for (i = 0;i < totalObj; i++){
    timeArray[i] = await getData('time', i);
    userArray[i] = await getData('user', i);
}

while(!stopSort){
    var keepSorting = false;
    for(i = 0; i < totalObj ; i++){
        var target = await convertTime(timeArray[i]);
        for(j = i + 1 ; j < totalObj ; j++){
            var comparison = await convertTime(timeArray[j]);
            if(target > comparison){

                //Switch target time with comparison time so that the lower time is up front
                var temp = timeArray[i];
                timeArray[i] = timeArray[j];
                timeArray[j] = temp;

                //Then switch the users around so that the user always corresponds with their time
                var userTemp = userArray[i];
                userArray[i] = userArray[j];
                userArray[j] = userTemp;

                //The loop will continue if even a single switch is made
                keepSorting = true;
            }
        }
    }

    if(!keepSorting){
        stopSort = true;
    }
}

//String building starts here
var placeArray = [':first_place: **1st', ':second_place: **2nd', ':third_place: **3rd', '**4th', '**5th', '**6th', '**7th', '**8th', '**9th', '**10th'];
for(i = 0; i < totalObj; i++){
    string = await string.concat(placeArray[i] + ": " + userArray[i] + "** - " + timeArray[i] + " \n\n");
    console.log('butt');
}


console.log("This String:" + string);
return string;

} }

I think problem is you are trying to await function with callback, it will not work => access to data.time may run before data = result[value] .我认为问题是您正在尝试使用回调await函数,它不起作用 => 访问data.time可能会在data = result[value]之前运行。 If you need await callback, you can use custom Promise (or use util.promisify, more info here )如果你需要等待回调,你可以使用自定义Promise (或使用 util.promisify,更多信息在这里

Promise:承诺:

function findStats(options) {
        return new Promise((resolve, reject) => {
            return stats.find(options, function (err, result) {
                if (err) {
                    return reject(err)
                }
                return resolve(result)
            })
        })
    }

utils.promisify utils.promisify

const util = require('util');
const findStats = util.promisify(stats.find);

Now you can use await in your function现在您可以在函数中使用 await

async function getData(field, value) {
    try {
        const result = await findStats({})
        const data = result.value

        if (field === 'user') {
            return data.user
        }
        if (field === 'time') {
            return data.time
        }
        return 0
    } catch (error) {
        // here process error the way you like
        // or remove try-catch block and sanitize error in your wrap function
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Node.js Discord.js UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“calculatedPosition” - Node.js Discord.js UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'calculatedPosition' of undefined 类型错误:无法读取未定义 Discord.js node.js v12.16.3 的属性“第一个” - TypeError: Cannot read property 'first' of undefined Discord.js node.js v12.16.3 JavaScript,Discord.js,Node.js TypeError:无法读取未定义的属性“执行” - JavaScript,Discord.js, Node.js TypeError: Cannot read property 'execute' of undefined node.js discord.js 无法读取未定义的属性“发送” - node.js discord.js cannot read property 'send' of undefined Node.js + Discord.js:无法读取未定义的属性“类” - Node.js + Discord.js: Cannot read property 'class' of undefined Node.js无法读取未定义的属性'then' - Node.js cannot read property 'then' of undefined Node.js无法读取未定义的属性&#39;on&#39; - Node.js Cannot read property 'on' of undefined discord.js错误TypeError:无法读取未定义的属性“ voiceChannel” - discord.js Error TypeError: Cannot read property 'voiceChannel' of undefined Discord.JS:TypeError:无法读取未定义的属性“角色” - Discord.JS:TypeError: Cannot read property 'roles' of undefined Discord.js:无法读取未定义的属性“ set” - Discord.js: Cannot read property 'set' of undefined
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM