我正在使用discord.js制作一个Discorde机器人,它可以监听Discorde服务器中的斜线命令,并操作Google工作表上的数据.在try 建立一个命令确认系统时,我遇到了一个令人沮丧的问题.问题出在getConfirment()方法上.相关代码如下:

    async execute(interaction) {
        try {
            await interaction.deferReply();
               
            // get player from spreadsheet
            const iss = interaction.options.getInteger("iss");
            const player = await getPlayerByISS(iss);

            // get confirmation
            let hasConfirmed = await getConfirmation(interaction, player);

            if (!hasConfirmed) {
                await interaction.editReply("Draft choice ab和oned.");
                return;
            }

            // if confirmed, draft the player
            let draftedPlayer = await draftPlayer(interaction.user.tag, player);

            await interaction.editReply(draftedPlayer);
        } catch (error) {
            console.log(error);
            await interaction.editReply("Could not draft player");
        }
    }

async function getConfirmation(interaction, player) {
    try {
        // send confirmation msg
        const message = await interaction.channel.send({
            content: `Are you sure you want to draft ${formatPlayerString(
                player
            )}?`
        });

        const filter = (reaction, user) => {
            return (
                ["????", "????"].includes(reaction.emoji.name) &&
                user.id === interaction.user.id
            );
        };

        // react to the msg to allow for easier reacting
        await Promise.all([message.react("????"), message.react("????")]);

        // awaitReactions just returns a list of all reaction objs that match above     
        // filter
        let didConfirm, responseMessage;
        message
            .awaitReactions({
                filter,
                max: 1,
                time: 60000,
                errors: ["time"],
            })
            .then((collected) => {
                const reaction = collected.first();

                didConfirm = reaction.emoji.name === "????";
                responseMessage = didConfirm
                    ? "Confirmed. Drafting now..."
                    : "Cancelled confirmation.";
            })
            .catch((collected) => {
                console.log(collected);

                responseMessage =
                    "Did not receive response in time. Ab和oning...";
                didConfirm = false;
            })
            .finally(async (collected) => {
                // clean up after 3s to prevent clutter
                setTimeout(() => message.delete(), 3000);

                // resolve the promise
                await message.edit(responseMessage);
                return didConfirm;
            });
    } catch (error) {
        console.log("Errored out : ", JSON.stringify(error));
        console.log(error);
        throw error;
    }
}

Sorry for the large chunk of code but let me explain. I want the bot to send a confirmation message, listen for any reaction replies to the message, 和 then proceed with drafting the player if the user who sent the /draft comm和 reacts with a thumbs up emoji, 和 ab和ons otherwise.

The issue is with the getConfirmation() method. Despite me having designated getConfirmation() as an async method, which should wrap my response in a promise 和 awaiting it, the code in execute() continues to run immediately after the await getConfirmation() line. It sets hasConfirmed = undefined 和 proceeds with that assumption. So no matter what the user reacts, the code will reach the !hasConfirmed block, 和 respond with "Draft choice ab和oned".

However, this does not make any sense to me. Since getConfirmation() is an async method, 和 we are awaiting it in another async method, shouldn't the await keyword halt execution until the promise has been fulfilled 和 hasConfirmed has a value? The confirmation message sent in getConfirmation does get correctly updated when the user reacts though, so I know that that code is being reached. Am I missing something obvious? Do I just fundamentally misunderst和 asynchronous programming?

如果能帮上忙,我将不胜感激!非常感谢.

编辑:菲尔的回答是肯定的

推荐答案

getConfirmation()不返回任何内容,因此将始终解析为undefined.仅供参考finally()的返回值不用于解析promise 链

// Quick demo showing what happens with finally
Promise.resolve(undefined).finally(() => "finally").then(console.log);

另外,最好不要把async / await.then() / .catch()混为一谈,因为它很快就会让人感到困惑.

相反,我会这样构造代码的await reactions部分

let didConfirm, responseMessage;
try {
  const collected = await message.awaitReactions({
    filter,
    max: 1,
    time: 60000,
    errors: ["time"],
  });

  const reaction = collected.first();

  didConfirm = reaction.emoji.name === "????";
  responseMessage = didConfirm
    ? "Confirmed. Drafting now..."
    : "Cancelled confirmation.";
} catch (err) {
  console.warn(err);
  responseMessage = "Did not receive response in time. Abandoning...";
  didConfirm = false;
}

// Things after an async try..catch is similar to finally
// only you can actually return a value

// clean up after 3s to prevent clutter
setTimeout(() => message.delete(), 3000);

// resolve the promise
await message.edit(responseMessage);
return didConfirm;

Javascript相关问答推荐

无法在page. evalve()内部使用外部函数

有Angular 的material .未应用收件箱中的价值变化

使用json文件字符串来enum显示类型字符串无法按照计算的enum成员值的要求分配给类型号

IMDB使用 puppeteer 加载更多按钮(nodejs)

为什么我的includes声明需要整个字符串?

如何在Javascript中的控制台上以一行形式打印循环的结果

如何禁用附加图标点击的v—自动完成事件

仅针对RTK查询中的未经授权的错误取消maxRetries

在网页上添加谷歌亵渎词

Promise Chain中的第二个useState不更新

如何从Intl.DateTimeFormat中仅获取时区名称?

无法使用单击按钮时的useState将数据从一个页面传递到另一个页面

我在Django中的视图中遇到多值键错误

使用领域Web SDK的Vite+Vue应用程序中的Web程序集(WASM)错误

类构造函数不能在没有用With Router包装的情况下调用

当标题被点击时,如何使内容出现在另一个div上?

图表4-堆叠线和条形图之间的填充区域

输入的值的类型脚本array.排序()

Node.js错误: node 不可单击或不是元素

ReferenceError:无法在初始化之前访问setData