問題描述
我一直想在用戶按下 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_modulesexpresslib
outerlayer.js:95:5)在下一個(C:Users eddyDesktopVerify
ode_modulesexpresslib
outer
oute.js:137:13)在 Route.dispatch (C:Users eddyDesktopVerify
ode_modulesexpresslib
outer
oute.js:112:3)在 Layer.handle [as handle_request] (C:Users eddyDesktopVerify
ode_modulesexpresslib
outerlayer.js:95:5)在 C:Users eddyDesktopVerify
ode_modulesexpresslib
outerindex.js:281:22在 Function.process_params (C:Users eddyDesktopVerify
ode_modulesexpresslib
outerindex.js:335:12)在下一個(C:Users eddyDesktopVerify
ode_modulesexpresslib
outerindex.js:275:10)在 expressInit (C:Users eddyDesktopVerify
ode_modulesexpresslibmiddlewareinit.js:40:5)在 Layer.handle [as handle_request] (C:Users eddyDesktopVerify
ode_modulesexpresslib
outerlayer.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_modulesexpresslib
outerlayer.js:95:5)
at next (C:Users eddyDesktopVerify
ode_modulesexpresslib
outer
oute.js:137:13)
at Route.dispatch (C:Users eddyDesktopVerify
ode_modulesexpresslib
outer
oute.js:112:3)
at Layer.handle [as handle_request] (C:Users eddyDesktopVerify
ode_modulesexpresslib
outerlayer.js:95:5)
at C:Users eddyDesktopVerify
ode_modulesexpresslib
outerindex.js:281:22
at Function.process_params (C:Users eddyDesktopVerify
ode_modulesexpresslib
outerindex.js:335:12)
at next (C:Users eddyDesktopVerify
ode_modulesexpresslib
outerindex.js:275:10)
at expressInit (C:Users eddyDesktopVerify
ode_modulesexpresslibmiddlewareinit.js:40:5)
at Layer.handle [as handle_request] (C:Users eddyDesktopVerify
ode_modulesexpresslib
outerlayer.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 thisPromise { <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 .thenThis 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 tothen()
, 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 atry...catch
statement. If any Promises inside of thetry
block are rejected, the code inside thecatch
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
這篇關于如何正確執行 createReactionCollection的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!