Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我无法在事件回调中捕获discord.js承诺拒绝?_Javascript_Node.js_Asynchronous_Es6 Promise_Discord.js - Fatal编程技术网

Javascript 为什么我无法在事件回调中捕获discord.js承诺拒绝?

Javascript 为什么我无法在事件回调中捕获discord.js承诺拒绝?,javascript,node.js,asynchronous,es6-promise,discord.js,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

所以我在制造一个不和谐机器人。为了简单起见,这里有一小部分说明了我的问题:

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();
当我运行这段代码时,我希望输出被承诺拒绝捕获,并且进程应该随后退出。但事实并非如此。相反,我得到了一个
promisejectionwarning
,并且进程没有退出(我必须按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();
然而,在这种情况下,输出与预期完全一致;我从捕获中看到了线,进程立即退出。没有捕获,我得到了未处理的承诺拒绝错误和未完成的过程


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

原因是,因为您的第二个代码不是discord事件发射器的工作方式,也不是内置于eventemitter的Node.js

ready
事件的回调函数没有使用
wait
执行,并且它没有附加
.catch
处理程序,这就是为什么会出现
未处理PromisejectionWarning
的原因

在EventEmitter回调中使用
async
时,您应该处理错误,如果不处理,您将收到警告,因为没有其他代码在处理它

client.on('ready', async () => {
  try {
     throw new Error('Omg');
  } catch(e) {

  }
});
在您的特定情况下,如果在“准备就绪”上满足某些条件,您似乎希望触发一个错误。因此,您应该做的是将侦听器包装在一个
承诺中

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');
  }
}

这将使您获得预期的行为

,因此,请澄清一下,您的意思是,由于('ready')
上的
事件本身没有使用
.catch
进行处理,因此承诺拒绝基本上被忽略了?换句话说,,这是否意味着,如果没有调用代码中的
async
/
wait
关键字,承诺拒绝也不会传播,如果没有显式的
reject
,您会建议使用您提到的第二种方法,还是只捕获每个错误处理程序中的错误?我是说,除非如果在('ready')
回调中捕捉到
错误,将触发未处理的PromisejectionWarning,因为没有人捕捉到该错误,这是您的责任。关于我的建议,这取决于您试图实现的目标,如果您实际展示了
ready
实现,将更容易为您提供最佳解决方案。我的整个ready函数太大了,但我的想法是,如果我在任何回调(on ready,on message)中不知何故错过了未处理的承诺,它会在更高的级别被捕获(在
.login
方法周围的try-catch块中)。这样,在这样的场景中就不会出现任何意外的进程退出(只是一些日志记录)。该消息确实指出,在将来,此类错误将导致退出。现在我明白了,如果不在每个回调的代码中包装一个try-catch,我的方法实际上是不可能的。谢谢你的澄清。