我正在编写一个Discord Bot,它使用MongoDB作为自定义命令和自定义反应的数据库。这是困扰我一段时间的问题。奇怪的是,这个问题有时会发生,而其他时候则不然。基本上,我的代码为:
const MongoClient = require('mongodb').MongoClient;
var db;
var cc;
var reactions;
MongoClient.connect('mongodb://<username>:<password>@ds020218.mlab.com:20218/zilla-bot-gamma', { useNewUrlParser: true }, (err, client) => {
if(err) console.log(err);
console.log('Connected to database!');
db = client.db('zilla-bot-gamma');
db.collection('cc').find().toArray((err, results) => {
if(err) console.log(err);
cc = results[0];
});
db.collection('reactions').find().toArray((err, results) => {
if(err) console.log(err);
reactions = results[0];
});
});
exports.reactEmoji = function(messageContent) {
var reactEmojicontents = [];
var j=0;
for(var i=0; i<reactions.list.length; i++) {
if(messageContent.toLowerCase().indexOf(reactions.list[i].trigger) >= 0) {
reactEmojicontents[j] = reactions.list[i].output;
j++;
}
}
if(reactEmojicontents[0]) {
return reactEmojicontents;
}
return 'None';
}
我的名为reactions
的数据库集合将是:
{
"_id": {
"$oid": "hidden"
},
"list": [
{
"trigger": "jason",
"output": "407194701515587584"
},
{
"trigger": "nitro",
"output": "476637660417359872"
},
{
"trigger": "pritt",
"output": "🍍"
},
{
"trigger": "kappa",
"output": "392389534064574473"
},
{
"trigger": "zilla",
"output": "392389485578420224"
},
{
"trigger": "tamz",
"output": "392363229906599948"
},
{
"trigger": "hello",
"output": "484051886677426176"
},
{
"trigger": "node",
"output": "484966646029484033"
},
{
"trigger": "heroku",
"output": "485798141791043584"
},
{
"trigger": "even",
"output": "486235385098403847"
}
]
}
运行此脚本后,我在cmd上收到以下消息:
Connected to database!
C:\JSFolder\ZillaBotGamma\Messages\msghandle.js:332
for(var i=0; i<reactions.list.length; i++) {
^
TypeError: Cannot read property 'list' of undefined
at exports.reactEmoji (C:\JSFolder\ZillaBotGamma\Messages\msghandle.js:332:30)
at Client.bot.on (C:\JSFolder\ZillaBotGamma\main.js:228:24)
at Client.emit (events.js:159:13)
at MessageCreateHandler.handle (C:\JSFolder\ZillaBotGamma\node_modules\discord.js\src\client\websocket\packets\handlers\MessageCreate.js:9:34)
at WebSocketPacketManager.handle (C:\JSFolder\ZillaBotGamma\node_modules\discord.js\src\client\websocket\packets\WebSocketPacketManager.js:103:65)
at WebSocketConnection.onPacket (C:\JSFolder\ZillaBotGamma\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:333:35)
at WebSocketConnection.onMessage (C:\JSFolder\ZillaBotGamma\node_modules\discord.js\src\client\websocket\WebSocketConnection.js:296:17)
at WebSocket.onMessage (C:\JSFolder\ZillaBotGamma\node_modules\ws\lib\event-target.js:120:16)
at WebSocket.emit (events.js:159:13)
at Receiver._receiver.onmessage (C:\JSFolder\ZillaBotGamma\node_modules\ws\lib\websocket.js:137:47)
我发现这很奇怪。 react.list明确定义为数据库中的数组,并在显示“已连接到数据库!”后弹出此错误消息。然后我认为这是因为db.collection().get()
中回调的异步性质,所以我尝试将回调定义为异步并放置reactions = await results[0]
。这并没有削减它。
谁能告诉我发生了什么事?
一些额外的信息:
此调用正在填充反应。
db.collection('reactions').find().toArray((err, results) => {
if(err) console.log(err);
reactions = results[0];
});
如果由于某种原因,在调用reactEmoji方法之前此调用失败或未完成,则会出现错误。
在尝试访问其中的属性之前,您应该确保反应具有值集。
if(Boolean(reactions)) {
for(var i=0; i<reactions.list.length; i++) {
if(messageContent.toLowerCase().indexOf(reactions.list[i].trigger) >= 0) {
reactEmojicontents[j] = reactions.list[i].output;
j++;
}
}
}
然后,您可以填充列表并调用该方法。我个人会创建一个名为getReactions()
的方法,它返回一个promise或使用一个回调来使用,如果没有设置反应。
编辑:这样的事情
async function getReactions() {
return new Promise(function (resolve, reject){
db.collection('reactions').find().toArray((err, results) => {
if(err) reject(err.message);
resolve(results[0]);
});
});
}
你可以这么称呼它。
let reactions = await getReactions();