簡體   English   中英

使用 Node.js、Mongoose 和 Discord.js 的未定義錯誤 [無法讀取未定義的屬性]

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

我一直在尋找類似的問題,但似乎還沒有找到適合我的解決方案。 所以我正在開發一個 Discord 機器人,它從 MongoDB 數據庫中獲取數據並使用 Mongoose 以不和諧嵌入消息的形式顯示所述數據。 在大多數情況下,一切正常,但是我的代碼的一小部分給我帶來了麻煩。 所以我需要導入一個包含所有可用用戶和每個用戶的“時間”數據的數組。 這是我用來導入所述數據的代碼塊:

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

現在這個 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;
}

所以 for 循環是我目前的錯誤所在。 當我嘗試運行此代碼並通過不和諧消息顯示我的數據時,出現此錯誤並且消息未發送:

(節點:13936)未處理的承諾拒絕警告:類型錯誤:無法讀取未定義的屬性“時間”

現在奇怪的是,這個錯誤並不是每次都發生。 如果我繼續從我的不和諧服務器調用觸發此代碼的命令,如果該命令實際顯示消息或給出此錯誤,則幾乎就像是 50/50 鏡頭。 這是非常不一致的。

這個錯誤讓我感到困惑,因為未定義的部分對我來說沒有意義。 在 mongoDB 集合中搜索的對象是明確定義的,for 循環永遠不會超過存在的對象數量。 我唯一的結論是我的異步函數設計有問題。 我曾嘗試更改代碼以減少使用 getData 函數,或者根本不使用等待或異步設計,但是這使我的最終不和諧消息包含幾個未定義的變量並最終導致崩潰。

如果有人有任何意見或建議,將不勝感激。 僅供參考,這里是接收數據、對其進行排序並准備要在不和諧服務器上顯示的字符串的完整函數(盡管錯誤似乎只發生在第一個 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;

}

我認為問題是您正在嘗試使用回調await函數,它不起作用 => 訪問data.time可能會在data = result[value]之前運行。 如果你需要等待回調,你可以使用自定義Promise (或使用 util.promisify,更多信息在這里

承諾:

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

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

現在您可以在函數中使用 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM