我目前正在开发一款不和谐的机器人,我想实现的命令之一是使用edit
命令编辑该机器人先前通过其发送的消息-我正在使用{{3}为此,从文档中看来,我似乎需要使用promise链来实现我想要的功能,但是我在一些小片段上有些困惑。我当前的代码如下:
module.exports = {
name: 'edit',
description: 'Edit one of the bot\'s messages',
args: true, // does the command have arguments?
guildOnly: true, // can this command be used outside of the discord channel?
execute(message, args) {
if (args.length < 2) {
console.log("Insufficient arguments provided");
return;
}
const server = message.guild;
let id = args.shift();
let newMessage = args.join(' ');
let channels = server.channels;
for (let [, channel] of channels) {
if(channel.type === 'text') {
channel.fetchMessage(id)
.then(response => {
return response;
}, _reason => {
console.log("still looking");
})
.then(function (message) {
message.edit(newMessage)
.then(editedMessage => {
console.log(`new message content: ${editedMessage}`);
})
.catch(console.error);
})
}
}
},
};
基本上,我的思考过程如下:可以在任何通道中使用该命令来编辑任何其他通道中的bot消息-为此,我需要循环浏览所有服务器通道并检查适当的消息ID(如上for循环所示)-这是我感到困惑的地方,fetchMessage
命令(见discord.js)返回了一个promise,但是我主要担心的是,如果消息是不是,我希望该机器人继续查找直到找到它。一旦完成,我会尝试将另一个承诺链接到实际的here;这时,我会向不一致的人发送一条消息,指出该过程已成功完成-从现在开始,一旦检查了第一个通道并且没有找到消息,我的代码当前就会出错,这可能是由于{ {1}}块。我的问题是:如果程序在第一次尝试中未找到消息,如何使程序不出错呢?如果确实找到了正确的消息,我该如何保证正确地编辑它呢?
答案 0 :(得分:0)
我建议您添加一个channel
参数,但是如果您确实想按自己的方式做,则只需捕获fetchMessage()
。另外,我不了解您第一个.then()
的目的。这是我的处理方式:
if (args.length < 2) {
console.log("Insufficient arguments provided");
return;
}
const server = message.guild;
let id = args.shift();
let newMessage = args.join(" ");
let channels = server.channels;
for (let [, channel] of channels) {
if (channel.type === "text") {
channel
.fetchMessage(id)
.then(message => {
message.edit(newMessage).then(editedMessage => {
console.log(`new message content: ${editedMessage}`);
});
})
.catch(e => console.log("Not this channel"););
}
}
答案 1 :(得分:0)
假设它是一个数组(或可以转换为数组),message.guild.channels
可以通过首先形成一个.catch()
链进行异步扫描,该链在下面以基于Array.prototype.reduce()的模式构建。
module.exports = {
'name': 'edit',
'description': 'Edit one of the bot\'s messages',
'args': true,
'guildOnly': true,
execute(message, args) {
if (args.length < 2) {
return Promise.reject(new RangeError('Insufficient arguments provided')); // ensure that execute() returns a Promise
}
let id = args.shift();
let newMessage = args.join(' ');
return message.guild.channels.reduce((rejetedPromise, [, channel]) => { // assuming `message.guild.channels` to be Array
return rejetedPromise.catch(error => {
if (channel.type === 'text') {
return channel.fetchMessage(id); // will resolve to `msg` if found and drop through to the then() below,
// otherwise will reject and flow will keep going to the next catch formed by the reduction.
} else {
throw new Error('channel(s) searched but message not found'); // keep going to next catch
}
});
}, Promise.reject('no channels')) // starter Promise for the reduction. If `message.guild.channels.length === 0`, this promise will fall straight through to the .catch() below
.then(msg => msg.edit(newMessage)) // execution will arrive here only if a `channel.fetchMessage(id)` above succeeds.
.then(editedMessage => { // this whole clause is optional.
console.log(`new message content: ${editedMessage}`);
return editedMessage; // return whatever is of interest to execute()'s caller.
})
.catch(error => { // this whole clause is optional.
console.error(error);
throw error; // rethrow error to inform execute()'s caller of the error.
});
}
};
message.guild.channels.reduce(...)
块说明了一些问题。
它构造了一个捕获链,如果手动构建,则捕获链的形式为:
Promise.reject().catch(...).catch(...).catch(...).catch(...).then(...);
将其与更熟悉(且更易于理解)的链条进行比较:
Promise.resolve().then(...).then(...).then(...).catch(...);
捕捞链的本质是其解决:
.then()
。 因此,您将获得所需的东西-机器人可以继续在一个频道中查找,直到找到所需的消息为止。