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

Javascript 使用Node.js、Mongoose和Discord.js的未定义错误[无法读取未定义的属性],javascript,node.js,mongodb,mongoose,discord.js,Javascript,Node.js,Mongodb,Mongoose,Discord.js,我一直在寻找类似的问题,但似乎还没有找到一个对我来说非常有效的解决方案。所以我正在开发一个Discord机器人,它从MongoDB数据库获取数据,并使用Mongoose以Discord嵌入消息的形式显示所述数据。在大多数情况下,一切正常,但我的代码中有一小部分给我带来了麻烦。 所以我需要导入一个包含所有可用用户和每个用户的“时间”数据的数组。以下是我用于导入上述数据的代码块: for (i = 0;i < totalObj; i++){ timeArray[i] = await g

我一直在寻找类似的问题,但似乎还没有找到一个对我来说非常有效的解决方案。所以我正在开发一个Discord机器人,它从MongoDB数据库获取数据,并使用Mongoose以Discord嵌入消息的形式显示所述数据。在大多数情况下,一切正常,但我的代码中有一小部分给我带来了麻烦。 所以我需要导入一个包含所有可用用户和每个用户的“时间”数据的数组。以下是我用于导入上述数据的代码块:

for (i = 0;i < totalObj; i++){
    timeArray[i] = await getData('time', i);
    userArray[i] = await getData('user', i);
}
所以for循环就是我当前的错误所在。当我尝试运行此代码并通过discord消息显示数据时,我收到此错误,消息未被发送:

(节点:13936)未处理的PromisejectionWarning:TypeError:无法读取未定义的属性“time”

奇怪的是,这种错误并非每次都会发生。如果我继续从discord服务器调用触发此代码的命令,如果该命令实际显示消息或给出此错误,则几乎就像50/50快照一样。这是非常不一致的

这个错误让我很困惑,因为未定义的部分对我来说没有意义。在mongoDB集合中搜索的对象是明确定义的,for循环从不超过存在的对象数。我唯一的结论是我的异步函数设计有问题。我尝试过修改代码以减少使用getData函数的频率,或者根本不使用waitis或异步设计,但是这会留下一些未定义的变量和最终的崩溃

如果有人有任何意见或建议,我们将不胜感激。仅供参考,以下是接收数据、对数据进行排序并准备显示在discord服务器上的字符串的完整函数(尽管错误似乎只发生在第一个for循环中):

异步函数buildString(){
var字符串=”;
var totalObj;
var timeArray=[];
var userArray=[];
var stopSort=false;
wait stats.find({},函数(err,result){
如果(错误){
结果。发送(错误);
}否则{
totalObj=结果长度;
}
});
对于(i=0;i比较){
//将目标时间与比较时间切换,使较低的时间提前
var temp=时间数组[i];
timeArray[i]=timeArray[j];
时间数组[j]=温度;
//然后切换用户,以便用户始终与他们的时间相对应
var userTemp=userArray[i];
userArray[i]=userArray[j];
userArray[j]=userTemp;
//即使只做了一个开关,循环也会继续
keepSorting=true;
}
}
}
如果(!keepSorting){
stopSort=true;
}
}
//弦建筑从这里开始
变量placeArray=[':第一名:*1',':第二名:*2',':第三名:*3','**4','**5','**6','**7','**8','**9','**10'];
对于(i=0;i

}

我认为问题在于您试图用回调函数等待
函数,它将不起作用=>访问
数据。时间可能在
数据=结果[值]
之前运行。如果需要等待回调,可以使用自定义
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)
            })
        })
    }
最终承诺

const util = require('util');
const findStats = util.promisify(stats.find);
现在您可以在函数中使用wait

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
    }
}

非常感谢您,通过使用自定义承诺策略,程序现在运行得非常好!
const util = require('util');
const findStats = util.promisify(stats.find);
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
    }
}