为什么我无法在事件回调中发现discord.js承诺被拒绝?

时间:2019-05-11 22:45:51

标签: javascript node.js asynchronous es6-promise discord.js

所以我要制造一个不和谐的机器人。为简单起见,这是一个非常小部分,它说明了我的问题:

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();

但是,在这种情况下,输出完全符合预期;我从捕获中看到了这一行,该过程立即退出。没有抓住,我会遇到未处理的承诺拒绝错误和未完成的过程。

所以我的问题是:为什么我无法在事件回调(例如on('ready'))中捕获承诺拒绝?

1 个答案:

答案 0 :(得分:1)

原因是因为您的第二个代码不是不和谐事件发射器的工作方式,也不是EventEmiter中内置的Node.js的工作方式。

ready事件的回调函数未与await执行,并且没有附加.catch处理程序,这就是为什么要获得{{1 }}。

在EventEmitter回调中使用UnhandledPromiseRejectionWarning时,应该处理该错误,否则请得到警告,因为没有其他代码在处理该错误。

async

在您的特定情况下,如果在“就绪”条件下满足某些条件,则似乎要触发错误。因此,您应该做的是将监听器包装在client.on('ready', async () => { try { throw new Error('Omg'); } catch(e) { } }); 中。

Promise

这将为您带来预期的行为