gpt4 book ai didi

javascript - Discord.js - 尝试等待异步进程并允许包装器的递归调用

转载 作者:行者123 更新时间:2023-12-03 00:13:20 30 4
gpt4 key购买 nike

这个有大量的移动部件,我已经尽力简化它们,并且我仍在学习异步/等待处理,所以请耐心等待 -

所以我尝试使用discord.js 为Discord 聊天机器人编写聊天命令。我遇到问题的命令是由以 !aut 开头的消息触发的,该命令应该接收一串用户输入(位于命令本身之后)并返回另一个字符串;如果用户没有提供字符串,我希望它获取紧邻包含命令的消息上方的消息内容(即第二个最新消息)并将其用作输入字符串。

但是,测试后一种情况时,它不断抛出此错误:(节点:17896)UnhandledPromiseRejectionWarning:DiscordAPIError:无法发送空消息

我用一个事件监听器构建了机器人,该事件监听器监听命令并在检测到命令时调用包装函数 execute(string, channel);然后,包装器为该命令调用适当的实用程序函数来获取一个字符串,然后将其传递回监听器,然后监听器将字符串发送到 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 是异步的 - 或者至少返回一个 Promise - 所以我也尝试使包装器异步,这样我就可以强制它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),这是我在将一个字符串输出命令的输出通过管道传输到另一个字符串输入命令时执行的操作。 (这也是为什么包装器首先存在,而不是监听器直接链接到实用程序函数)这涉及 execute 本身内的 execute 调用。我就link to pastebin此时,它会抛出类型错误,因为它无法从嵌套的 execute 中获取值,因此它最终会尝试调​​用 null.then:

(node:6796) UnhandledPromiseRejectionWarning: TypeError: pInnerPromise.then is not a function

如何构建我的代码,以便它在继续之前正确等待 fetchMessages 查询,但仍然允许递归调用包装函数(或其他管道方式)?

最佳答案

你的代码

    if (executable(sInnerCom) == true) {
// here you are using await so promise is already resolved.
let pInnerPromise = await execute(sInnerCom, pChannel);
// no need to use then, you can return result direct
pInnerPromise.then(result => { sInnerComResult = result });
}

应该是这样的

   if (executable(sInnerCom) == true) {
let result = await execute(sInnerCom, pChannel);
sInnerComResult = result ;
}

或者像这样

if (executable(sInnerCom) == true) {
sInnerComResult = await execute(sInnerCom, pChannel);
}

关于javascript - Discord.js - 尝试等待异步进程并允许包装器的递归调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54625068/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com