在循环完成之前,ForEach 运行之后的代码



我正在尝试获取 discord 服务器中的角色列表,找到角色所有者、其成员及其代表,但是 INSERT 查询甚至在 ForEach 完成之前就发生了......我环顾四周,所有的解决方案都旧了,或者将我的代码从几行变成 100+ 行......

con.connect(function(err) {
        if (err) {
            console.log(err);
            return msg.reply({embed: {color: 16711686,description: "\❌ | Failed to connect to database - Contact **TheeDeer**"}})
             .then(say => {
                msg.delete();
                say.delete(3000);
              });
        }
        msg.guild.roles.forEach(function(role) {
            if (role.name !== "@everyone") {
                if (role.id !== "509854902525231106" || role.id !== "509864772154687488" || role.id !== "509862522921287692" || role.id !== "526336817386225675" || role.id !== "509852743909900321" || role.id !== "526336702298456064" || role.id !== "509872838891536384" || role.id !== "509870184115339286" || role.id !== "511409235364413446" || role.id !== "509850967932665857" || role.id !== "527116001880309762" || role.id !== "509864108024397849" || role.id !== "511409106683297792" || role.id !== "526897893181882388" || role.id !== "509864540129853450" || role.id !== "509870488634523648" || role.id !== "509869899490000897" || role.id !== "511420878664237056" || role.id !== "509850657164099604" || role.id !== "526336636523380758" || role.id !== "510975537733173259" || role.id !== "509855069584490498" || role.id !== "517564552108441626" || role.id !== "509868843863244800" || role.id !== "509857751728652289" || role.id !== "510974779818377227") {
                    var ID = role.id;
                    var clanName = role.name;
                    var clanMembers = [];
                    var clanOwner = "";
                    var clanRep = [];
                    role.members.forEach( function(member, index) {
                         member.roles.forEach( function(memberRole, index) {
                            if (memberRole.id == "509869899490000897" || memberRole.id == "509881406810357792") {
                               clanOwner = member.id;
                            } else if (memberRole.id == "509870184115339286") {
                                clanRep.push(member.id);
                            } else {
                                clanMembers.push(member.id);
                            }
                        });
                    });
                    clanRep = clanRep.toString();
                    clanMembers = clanMembers.toString();
                    if (!clanMembers || !clanOwner) { failedClans.push(clanName); return; }
                    clanList.push([ID,
                        clanName,
                        clanMembers,
                        clanOwner,
                        clanRep]
                    );
                    addedClans.push(clanName)
                }
            }
        });
        await console.log(clanList);
        var sql = "INSERT INTO clans (roleID,clanName,clanMembers,clanOwner,clanRep) VALUES ?";
        con.query(sql,[clanList], function (err, result, fields) {
            if (err) {
                console.log(err);
            }
            return msg.reply({embed: {color: 16711686,description: "Added the following clans n``` "+addedClans.toString()+" ```n Failed to add the following ``` "+failedClans.toString()+" ```"}});
        });
    });

为了解决这个问题,我建议您定义自己的自定义异步版本的forEach循环。这背后的理由是,您可以等待 foreach 循环的执行,它将解决您的问题。

步骤 1:定义您自己的异步版本的 forEach。

const asyncForEach = async (array, callback) => {
 for (let index = 0; index < array.length; index++) {
 await callback(array[index]);
  }
};

第 2 步:现在您可以在代码中使用"asyncForEach 版本,如下所示"

await asyncForEach(msg.guild.roles, yourcallbackfunction);
con.query(.....your insert query.....);
// now if you put your Sql insert query after the above awaited asyncForEach
// it will definitely execute only once your asyncForEach execution is 
// finished.

遇到了类似的情况,这个异步版本的foreach对我来说就像一个魅力,唯一的区别是我使用的是elasticsearch。

快乐编码:)

Array.forEach 正在阻塞,我怀疑那里可能有其他问题,即导致"clanList"未像您期望的那样填充的逻辑缺陷。

console.log() 主循环每次迭代上的整数计数器变量,只是为了查看它确实在 INSERT 语句之前执行。

我遇到了这个问题,我的研究对我有以下想法:

JavaScript forEach函数同步执行代码,无论是否使用带有 async 和 await 关键字(用于异步运行代码)

都使用它。

但是,它将以意外行为运行。

溶液:

  1. 将其中任何一个用于循环for(…;…;…)for ... of
  2. 如果 for 循环中的代码不必是顺序的,则此解决方案有效。使用Array.map()方法获取一系列承诺并使用Promise.all执行所有承诺
await Promise.all(
    msg.guild.roles.map(async (role) => {
      // execute your asynchronous functions
    })
);

最新更新