У этого есть тонна движущихся частей, которые я пытался максимально упростить, и я все еще изучаю асинхронную / ожидающую обработку, так что терпите меня -
Так что я пытаюсьписать команды чата для чат-бота Discord с помощью discord.js.Команда, с которой у меня возникли проблемы, вызванная сообщением, начинающимся с !aut
, должна принимать строку ввода пользователя (которая следует за самой командой) и возвращать другую строку;если пользователь не предоставляет строку, я хочу, чтобы он взял содержимое сообщения непосредственно над сообщением, содержащим команду (т. е. 2-ую самую последнюю), и использовал ее в качестве входной строки.
Однако, проверяя этоВ последнем случае он продолжает выдавать эту ошибку: (node:17896) UnhandledPromiseRejectionWarning: DiscordAPIError: Cannot send an empty message
Я структурировал бота с помощью прослушивателя событий, который прослушивает команды и вызывает функцию-оболочку execute(string, channel)
, если она обнаруживает;Оболочка затем вызывает соответствующую служебную функцию для этой команды, чтобы получить строку, которая затем возвращается обратно в прослушиватель, который затем отправляет строку в канал.
Функция полезности com_aut(array)
работает отлично;проблема в том, что пустая строка по умолчанию sComResult
, определенная в оболочке, возвращается слушателю, прежде чем она может быть перезаписана с помощью com_aut
:
client.on('message', pMessage => {
if (executable(pMessage.content) == true) {
let sResult = execute(pMessage.content, pMessage.channel);
pMessage.channel.send(sResult);
}
});
function execute(sMessage, pChannel = null) {
// strip off the initial ! that marks the message as a command; whatever comes immediately afterwards is the command
let args = sMessage.substring(1).trim().split(/ +/g);
let cmd = args[0];
// don't include the command itself among the rest of the arguments passed to it
args = args.splice(1);
let sComResult = "";
switch(cmd){
...
case "aut":
if (args.length < 1) {
// input string that should be in args actually isn't, so grab the content of the 2nd most recent message instead
pChannel.fetchMessages({ limit: 2 }).then(pMessages => {
sComResult = com_aut([pMessages.last().content]);
});
} else {
// input string is present in args, so just use that
sComResult = com_aut(args);
}
break;
}
return sComResult;
}
TextChannel.fetchMessages
асинхронна - или возвращает обещаниепо крайней мере - поэтому я попытался сделать обертку также асинхронной, чтобы я мог принудительно установить ее на await
.Плюс необходимые изменения в слушателе, я обнаружил, что это сработало:
client.on('message', pMessage => {
if (executable(pMessage.content) == true) {
execute(pMessage.content, pMessage.channel).then(sResult => { pMessage.channel.send(sResult) });
}
});
async function execute(sMessage, pChannel = null) {
// strip off the initial ! that marks the message as a command; whatever comes immediately afterwards is the command
let args = sMessage.substring(1).trim().split(/ +/g);
let cmd = args[0];
// don't include the command itself among the rest of the arguments passed to it
args = args.splice(1);
let sComResult = "";
switch(cmd){
...
case "aut":
if (args.length < 1) {
// input string that should be in args actually isn't, so grab the content of the 2nd most recent message instead
pMessages = await pChannel.fetchMessages({ limit: 2 });
sComResult = com_aut([pMessages.last().content]);
});
} else {
// input string is present in args, so just use that
sComResult = com_aut(args);
}
break;
}
return sComResult;
}
Однако, СЕЙЧАС проблема в том, что я не могу вызвать execute(string, channel)
рекурсивно, что я делаю, когда передаю выходные данные одной строки-output в другую команду ввода строки.(Именно поэтому обертка существует в первую очередь вместо того, чтобы прослушиватель просто связывался напрямую с служебными функциями). Это включает в себя execute
вызов внутри самой execute
.Я просто ссылку на pastebin на данный момент, но он выдает ошибку типа, так как он не может получить значение из вложенного execute
и поэтому в итоге пытается вызвать null.then
:
(node:6796) UnhandledPromiseRejectionWarning: TypeError: pInnerPromise.then is not a function
Как я могу структурировать мой код так, чтобы он должным образом ожидал запроса fetchMessages перед тем, как двигаться дальше, но все же разрешал рекурсивный вызов функции-оболочки (или каким-либо другим способом передачи)?