所以我正在制作一个不和谐的机器人。为简单起见,这里是非常的一小部分来说明我的问题:
const Discord = require('discord.js');
const client = new Discord.Client();
client.on('ready', async () => {
throw new Error('Omg');
});
async function start() {
try {
await client.login(process.env.DISCORD_BOT_TOKEN);
} catch (err) {
console.error('Caught the promise rejections');
}
}
start();
当我运行这段代码时,我希望输出为 Caught the promise rejections
并且该进程随后应该退出。然而,这种情况并非如此。相反,我得到一个 PromiseRejectionWarning
并且进程没有退出(我必须按 Ctrl-C 才能退出)。我首先想到回调中的错误可能不会传播到调用它们的代码,所以我做了另一个纯 JS 示例:
const client = {
on(event, callback) {
this.callback = callback;
},
async login(token) {
while (true) {
// I assume the login method calls the callback in D.js
// (where else could it be called?)
await this.callback();
await sleep(5000);
}
},
};
client.on('ready', async () => {
throw new Error('Omg');
});
async function start() {
try {
await client.login(process.env.DISCORD_BOT_TOKEN);
} catch (err) {
console.error('Caught the promise rejections');
}
}
start();
但是在这种情况下,输出完全符合预期;我看到 catch 中的行,进程立即退出。如果没有捕获,我会得到未处理的 promise 拒绝错误和未完成的过程。
所以我的问题是:为什么我无法在我的事件回调(如 on('ready')
)中捕获 promise 拒绝?
最佳答案
原因是,因为您的第二个代码不是 discord 事件发射器的工作方式,EventEmiter 中内置的 Node.js 也不是。
ready
事件的回调函数未使用 await
执行,并且没有附加 .catch
处理程序它,这就是为什么您会收到 UnhandledPromiseRejectionWarning
的原因。
在 EventEmitter 回调中使用 async
时,您应该处理错误,否则您会收到警告,因为没有其他代码正在处理它。
client.on('ready', async () => {
try {
throw new Error('Omg');
} catch(e) {
}
});
在您的特定情况下,您似乎希望在“就绪”时满足某些条件时触发错误。因此,您应该做的是将该监听器包装在 Promise
中。
function discordReady(client) {
return new Promise((resolve, reject) => {
client.once('ready', async () => {
reject(new Error('Omg'));
// resolve..
});
})
}
async function start() {
try {
await Promise.all([
discordReady(client),
client.login(process.env.DISCORD_BOT_TOKEN),
]);
} catch (err) {
console.error('Caught the promise rejections');
}
}
这会让你得到预期的行为
关于javascript - 为什么我无法在事件回调中捕获 discord.js promise 拒绝?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56094829/