亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何等待此功能完成?

如何等待此功能完成?

蕭十郎 2022-07-21 22:30:33
在將數據發送到控制臺之前,我需要等待映射功能完成。我知道這與 Promise 有關。我已經嘗試了幾個小時,即使在閱讀了很多關于 Promise 和異步函數的內容之后,我也無法讓它工作......async function inactiveMemberWarner() {    var msg = "```javascript\nI have sent warnings to members that have been inactive for 2 weeks.\n\n"    var inactiveMembers = '';    var count = 0;    var guildMembers = client.guilds.find(g => g.name === mainGuild).members;    const keyPromises = await guildMembers.map(async (member) => {        if (isMod(member)) {            connection.query(`SELECT * from users WHERE userID='${member.id}'`, (err, data) => {                if (data[0]) {                    if (!data[0].warnedForInactivity && moment().isSameOrAfter(moment(data[0].lastMSGDate).add('2', 'week'))) {                        count++;                        var updateWarning = {warnedForInactivity: 1}                        connection.query(`UPDATE users SET ? WHERE userID='${data[0].userID}'`, updateWarning);                        member.send(`**[*]** WARNING: You've been inactive on \`\`${mainGuild}\`\` for 2 weeks. Members that have been inactive for at least a month will be kicked.`);                        inactiveMembers += `${count}. ${member.user.tag}\n`;                        return inactiveMembers;                    }                }            });        }    });    await Promise.all(keyPromises).then(inactiveMembersData => console.log(inactiveMembers)); // RETURNS AN EMPTY STRING    setTimeout(() => console.log(inactiveMembers), 5000); // RETURNS THE INACTIVE MEMBERS AFTER WAITING FOR 5 SECONDS (PRMITIVE WAY)}inactiveMemberWarner();先感謝您!
查看完整描述

2 回答

?
aluckdog

TA貢獻1847條經驗 獲得超7個贊

你很近,但不完全在那里。

首先,一些注意事項:

  • await可以用于任何值,但將它用于任何不是 Promise 的東西是完全沒有意義的。你guildMembers.map(...);返回一個數組,而不是一個 Promise。

  • 混合await.then(...)工作,但有點混亂。您已經在使用await- 為什么還要處理回調?

  • 像這樣使用guildMembers.map(async ...)將確保所有請求或多或少立即被觸發,并且它們可以按任何順序完成。這很好,但它是一種競爭條件,會導致或多或少隨機的結果順序。

  • 即使只是在概念上,這也不是一個好方法!每當您必須循環查詢時,請嘗試并研究僅在一個查詢中執行此操作的方法。SQL 相當強大。

您當前的代碼不起作用的原因是您的connection.query函數逃脫了異步控制流。我的意思是,使用 async/await 和 Promises 的全部意義基本上是在本地跟蹤回調,并利用 Promise 鏈來動態添加回調。如果您調用返回 Promise 的異步函數,您現在可以在代碼中的任何其他位置攜帶該 Promise 并動態地將成功處理程序附加到它:使用.then()或使用 sugar await

但是這個connection.query函數沒有返回一個 Promise,它只是讓你傳遞另一個裸回調——這個回調沒有被 Promise 跟蹤!Promise 沒有對該回調的引用,它不知道何時調用該回調,因此您的 async/await 控制流被轉義,并且您的 Promise 在查詢運行之前很久就解決了。

你可以通過在 async 函數中創建一個新的 Promise 來解決這個問題:

async function inactiveMemberWarner() {

    var msg = "```javascript\nI have sent warnings to members that have been inactive for 2 weeks.\n\n"

    var inactiveMembers = '';

    var count = 0;

    var guildMembers = client.guilds.find(g => g.name === mainGuild).members;


    const keyPromises = guildMembers.map(async (member) => {

        if (isMod(member)) {

            return new Promise((resolve, reject) => {

                connection.query(`SELECT * from users WHERE userID='${member.id}'`, (err, data) => {

                    if (err) reject(err); //make errors bubble up so they can be handled

                    if (data[0]) {

                        if (!data[0].warnedForInactivity && moment().isSameOrAfter(moment(data[0].lastMSGDate).add('2', 'week'))) {

                            count++;

                            var updateWarning = {warnedForInactivity: 1}

                            connection.query(`UPDATE users SET ? WHERE userID='${data[0].userID}'`, updateWarning);

                            member.send(`**[*]** WARNING: You've been inactive on \`\`${mainGuild}\`\` for 2 weeks. Members that have been inactive for at least a month will be kicked.`);

                            resolve(`${count}. ${member.user.tag}\n`;);

                        }

                    } else resolve(""); //make sure to always resolve or the promise may hang

                });

            });

        }

    });


    let inactiveMembersData = await Promise.all(keyPromises); // Returns an array of inactive member snippets.

    inactiveMembers = inactiveMembersData.join(""); //join array of snippets into one string

}


inactiveMemberWarner();

這會起作用,但是有一個更好的方法。SQL 支持IN運算符,它允許您擁有類似WHERE userID IN (list_of_ids). 換句話說,您可以在一個查詢中執行此操作。您甚至可以指定更多條件,例如warnedForInactivity = 0and lastMSGDate BETWEEN (NOW() - INTERVAL 14 DAY) AND NOW()。通過這種方式,您可以將所有當前的處理邏輯卸載到 SQL 服務器上——您幾乎每次都應該嘗試這樣做。它也會大大簡化這段代碼。我不會再進一步了,因為它超出了這個問題的范圍,但是如果您無法弄清楚,請隨時問另一個。


查看完整回答
反對 回復 2022-07-21
?
拉丁的傳說

TA貢獻1789條經驗 獲得超8個贊

我無法對此進行測試,但這通常對我有用的是當想要等待 smt 時:


async function inactiveMemberWarner() {

    new Promise(function(cb,rj){

        var msg = "```javascript\nI have sent warnings to members that have been inactive for 2 weeks.\n\n"

        var inactiveMembers = '';

        var count = 0;

        var guildMembers = client.guilds.find(g => g.name === mainGuild).members;

        const keyPromises = await guildMembers.map(async (member) => {

            if (isMod(member)) {

                connection.query(`SELECT * from users WHERE userID='${member.id}'`, (err, data) => {

                    if (data[0]) {

                        if (!data[0].warnedForInactivity && moment().isSameOrAfter(moment(data[0].lastMSGDate).add('2', 'week'))) {

                            count++;

                            var updateWarning = {warnedForInactivity: 1}

                            connection.query(`UPDATE users SET ? WHERE userID='${data[0].userID}'`, updateWarning);

                            member.send(`**[*]** WARNING: You've been inactive on \`\`${mainGuild}\`\` for 2 weeks. Members that have been inactive for at least a month will be kicked.`);

                            inactiveMembers += `${count}. ${member.user.tag}\n`;

                            cb(inactiveMembers);

                        }

                    }

                });

            }

        });

        cb('No Members');

    }).then(inactiveMembersData => console.log(inactiveMembers)); // SHOULD RETURNS THE INACTIVE MEMBERS

}


inactiveMemberWarner();


查看完整回答
反對 回復 2022-07-21
  • 2 回答
  • 0 關注
  • 135 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號