如何正确执行 createReactionCollection

2022-01-10 00:00:00 node.js express javascript discord.js

我一直想在用户按下 Check 或 X 的反应时创建一个事件.但是,当我使用该函数时,我收到一个错误消息对象不存在它.

我已经从 awaitReactions 回到了这个,但它没有工作.

我对 messageSent 对象做了一个 console.log 并得到了这个 Promise { <pending>}

var messageSent = user.send({embed}).then(函数(消息){message.react('✅')message.react('❎')});messageSent.createReactionCollection(r => ['✅','❎'].includes(r.emoji.name)).on('收集', r => {if (r.emoji.name == '✅') {user.send("已验证!✅")} else if (r.emoji.name == '❎') {user.send("取消!❎")}});}

TypeError: messageSent.createReactionCollection 不是函数在 app.post (C:Users	eddyDesktopVerifyapp.js:46:25)在 Layer.handle [as handle_request] (C:Users	eddyDesktopVerify
ode_modulesexpresslibouterlayer.js:95:5)在下一个(C:Users	eddyDesktopVerify
ode_modulesexpresslibouteroute.js:137:13)在 Route.dispatch (C:Users	eddyDesktopVerify
ode_modulesexpresslibouteroute.js:112:3)在 Layer.handle [as handle_request] (C:Users	eddyDesktopVerify
ode_modulesexpresslibouterlayer.js:95:5)在 C:Users	eddyDesktopVerify
ode_modulesexpresslibouterindex.js:281:22在 Function.process_params (C:Users	eddyDesktopVerify
ode_modulesexpresslibouterindex.js:335:12)在下一个(C:Users	eddyDesktopVerify
ode_modulesexpresslibouterindex.js:275:10)在 expressInit (C:Users	eddyDesktopVerify
ode_modulesexpresslibmiddlewareinit.js:40:5)在 Layer.handle [as handle_request] (C:Users	eddyDesktopVerify
ode_modulesexpresslibouterlayer.js:95:5)

解决方案

同步与异步

假设您打算接您的朋友去参加体育赛事.你不确定他们希望你什么时候来,所以你给他们打电话问他们.他们想了一会儿,然后告诉你一个时间.你得到了你要求的信息,所以你挂断了.在编程术语中,这将是同步代码的一个示例(有时被认为是 Node.js 中的普通"代码).

让自己回到同样的境地.然而,当你这次打电话给你的朋友时,他们很忙.你不想打扰他们,所以你让他们稍后给你打电话.你挂断了,但现在你等着.一个小时后,他们给你回电话,告诉你时间.这就是异步代码的思考过程.

屏幕后面还有很多内容,但为简单起见,我不会用所有这些信息轰炸你.

<小时>

承诺

<块引用>

Promise 对象表示异步操作的最终完成(或失败)及其结果值.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

让我们分解代码以更好地理解问题.

  • User.send() 返回一个 Promise.
  • Promise.then() 也返回一个 Promise.

因此,您的代码实际上是这样的:

var messageSent = Promise -->承诺

<块引用>

Promise 处于以下状态之一:

  • pending:初始状态,既不满足也不拒绝.
  • fulfilled:表示操作成功完成.
  • rejected:表示操作失败.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

<块引用>

我对 messageSent 对象做了一个 console.log,我得到了这个 Promise { <pending>}

虽然您将变量定义为 Promise,但它并没有立即完成,因此还没有返回任何值.它处于 pending 状态.

<小时>

解决方案

那么,我们如何检索 Promise 的结果?我们必须等待它.

  • 保持简单的流程,您可以使用 await 关键字.它所做的只是等待 Promise 被履行或拒绝,然后再继续执行进一步的代码.考虑以下示例:

    //需要使用'await'的异步上下文(意思是在异步函数中).var messageSent = await user.send(embed);等待 messageSent.react('✅');等待 messageSent.react('❎');//创建反应收集器.

  • 或者,您可以坚持使用 then() 链.回调将在 Promise 实现时使用返回的值调用.在某些情况下,这很简单.但是,回调很快就会变得混乱,并且返回值的范围会受到限制.考虑这个例子:

    user.send(embed).then(messageSent => {messageSent.react('✅').then(() => messageSent.react('❎')).then(() => {//创建反应收集器.});});//请记住,此处的代码将在 'user.send(embed).' 之后立即执行.

  • <块引用>

    我可能已经修复了它,由于某种原因它没有返回消息的对象,所以我将 messageSent = message; 添加到 .then

    这适用于您的情况,因为 then() 回调中的值将是已实现的 Promise,并且您将变量设置为返回值.不过,这不是最好的主意.


错误处理

当一个 Promise 被拒绝时,这意味着出现了问题.必须捕获源自被拒绝的 Promise 的错误.如果不是,您将在控制台中收到带有错误的警告.

  • 您可以附加 catch() 方法,这些方法的工作原理与 then() 类似,除了将错误作为回调参数返回并且仅在被拒绝时调用.考虑这个简短的例子:

    user.send(embed).then(messageSent => {...}).catch(console.error);

  • 您可以使用 try...catch 语句,而不是附加多个 catch() 方法.如果 try 块内的任何 Promise 被拒绝,则执行 catch 块内的代码.例如:

    try {const user = await bot.fetchUser('someID');等待用户.发送(嵌入);} 捕捉(错误){控制台.错误(错误);}

<小时>

资源

  • Discord.js 文档
  • MDN 文档

I've been wanting to create an event when a user presses a reaction that is a Check or X. Although, when I use the function I get an error that it doesn't exist for the message object.

I've already from awaitReactions back to this and it hasn't worked.

EDIT: I did a console.log to the messageSent object and I got this Promise { <pending> }

var messageSent = user.send({embed})
    .then(function (message) {
         message.react('✅')
         message.react('❎')
     });
messageSent.createReactionCollection(r => ['✅','❎'].includes(r.emoji.name))
     .on('collect', r => {
         if (r.emoji.name == '✅') {
             user.send("Verified! ✅")
          } else if (r.emoji.name == '❎') {
             user.send("Canceled! ❎")
          }
      });   
  }

TypeError: messageSent.createReactionCollection is not a function
    at app.post (C:Users	eddyDesktopVerifyapp.js:46:25)
    at Layer.handle [as handle_request] (C:Users	eddyDesktopVerify
ode_modulesexpresslibouterlayer.js:95:5)
    at next (C:Users	eddyDesktopVerify
ode_modulesexpresslibouteroute.js:137:13)
    at Route.dispatch (C:Users	eddyDesktopVerify
ode_modulesexpresslibouteroute.js:112:3)
    at Layer.handle [as handle_request] (C:Users	eddyDesktopVerify
ode_modulesexpresslibouterlayer.js:95:5)
    at C:Users	eddyDesktopVerify
ode_modulesexpresslibouterindex.js:281:22
    at Function.process_params (C:Users	eddyDesktopVerify
ode_modulesexpresslibouterindex.js:335:12)
    at next (C:Users	eddyDesktopVerify
ode_modulesexpresslibouterindex.js:275:10)
    at expressInit (C:Users	eddyDesktopVerify
ode_modulesexpresslibmiddlewareinit.js:40:5)
    at Layer.handle [as handle_request] (C:Users	eddyDesktopVerify
ode_modulesexpresslibouterlayer.js:95:5)

解决方案

Sync vs Async

Say you're planning on picking your friend up to go to a sporting event. You're not sure when they want you to come, so you call them on the phone and ask them. They think about it for a while, and then tell you a time. You got the information you requested, so you hang up. In programming terms, this would be an example of synchronous code (sometimes thought of as "normal" code in Node.js).

Put yourself back in the same situation. However, when you call your friend this time, they're very busy. You don't want to bother them so you ask them to call you later. You hang up, but now you wait. An hour later, they call you back and tell you the time. This is the thought process of asynchronous code.

There's a lot more that goes on behind the screen, but for simplicity's sake, I'm not going to bombard you with all that information.


Promises

The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Let's break the code down to better understand the problem.

  • User.send() returns a Promise.
  • Promise.then() also returns a Promise.

Therefore, your code really looks like this:

var messageSent = Promise --> Promise

A Promise is in one of these states:

  • pending: initial state, neither fulfilled nor rejected.
  • fulfilled: meaning that the operation completed successfully.
  • rejected: meaning that the operation failed.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

I did a console.log to the messageSent object and I got this Promise { <pending> }

Although you defined the variable as a Promise, it isn't completed right away, and therefore no value is returned yet. It's in its pending state.


Solutions

So, how do we retrieve the result of a Promise? We have to wait for it.

  • Keeping a simple flow, you can use the await keyword. All it does is wait for the Promise to be fulfilled or rejected before continuing the execution of further code. Consider the following example:

    // Asynchronous context (meaning within an async function) needed to use 'await.'
    
    var messageSent = await user.send(embed);
    
    await messageSent.react('✅');
    await messageSent.react('❎');
    
    // Create reaction collector.
    

  • Alternatively, you could stick to then() chains. The callback will be called with the returned value upon the fulfillment of the Promise. In some contexts, this is simple. However, callbacks can get messy very quickly, and the scope of the returned values will be limited. Consider this example:

    user.send(embed)
      .then(messageSent => {
        messageSent.react('✅')
          .then(() => messageSent.react('❎'))
            .then(() => {
              // Create reaction collector.
            });
      });
    
    // Keep in mind that the code here will be executed immediately after 'user.send(embed).'
    

  • I might have fixed it, for some reason it wasn't returning the object of the message so I added messageSent = message; to the .then

    This works in your case because the value in the then() callback will be the fulfilled Promise, and you're setting the variable to the returned value. This isn't the best idea, though.


Error Handling

When a Promise is rejected, it means something went wrong. Errors originating from rejected Promises must be caught. If they aren't, you'll receive a warning in the console with the error.

  • You can attach catch() methods which will work similarly to then(), except returning the error as its callback parameter and only being called upon rejection. Consider this short example:

    user.send(embed)
      .then(messageSent => {...})
      .catch(console.error);
    

  • Instead of attaching multiple catch() methods, you can use a try...catch statement. If any Promises inside of the try block are rejected, the code inside the catch block is executed. For example:

    try {
      const user = await bot.fetchUser('someID');
      await user.send(embed);
    } catch(err) {
      console.error(err);
    }
    


Resources

  • Discord.js Documentation
  • MDN Documentation

相关文章