使用 MessageComponentInteraction 收集器更新 Discord Message Embed 的更快更简洁的方法

Faster and cleaner way to update Discord Message Embed with a MessageComponentInteraction collector

我正在尝试为我的 discord 机器人 (TypeScript) 创建赛马命令。 代码本身工作正常,但我必须更新包含比赛和参与者的嵌入。问题是为了让它正确更新,我必须在每次 collector.on("collect") 触发时设置它的描述。我想问一下有没有更好、更高效、更干净的更新方式。谢谢!
代码:

    const bet = interaction.options.get("bet").value;

    class Horse {
      name: string;
      owner: User;
      speed: number;
      position: Array<string>;
      constructor(name: string) {
        this.name = name;
        this.owner = null;
        this.speed = 0;
        this.position = [""];
      }
    }

    const horses = [
      new Horse(aimless.pick(names, { remove: true })),
      new Horse(aimless.pick(names, { remove: true })),
      new Horse(aimless.pick(names, { remove: true })),
      new Horse(aimless.pick(names, { remove: false })),
    ];
    const hasJoined: Array<Horse["owner"]> = [];

    const row = new MessageActionRow();
    for (const horse of horses) {
      row.addComponents(
        new MessageButton()
          .setCustomId(horse.name)
          .setLabel(horse.name)
          .setStyle("SECONDARY")
      );
    }
    const embed = new MessageEmbed()
      .setTitle("Place your bets!")
      .setDescription(
        `**${horses[0].name} - ${
          horses[0].owner !== null ? horses[0].owner.username : "Nobody"
        } 
        ${horses[0].position}
        
        ${horses[1].name} - ${
          horses[1].owner !== null ? horses[1].owner.username : "Nobody"
        }
        ${horses[1].position}
        
        ${horses[2].name} - ${
          horses[2].owner !== null ? horses[2].owner.username : "Nobody"
        }
        ${horses[2].position} 
        
        ${horses[3].name} - ${
          horses[3].owner !== null ? horses[3].owner.username : "Nobody"
        }
        ${horses[3].position}**`
      );
    await interaction.editReply({
      embeds: [embed],
      components: [row],
    });
    const filter = async (i: MessageComponentInteraction) => {
      let profile: any;
      try {
        profile = await profileModel.findOne({ userID: i.user.id });
        if (!profile) {
          await profileModel.create({
            userID: i.user.id,
            serverID: i.guild?.id,
            username: i.user.username,
            bananas: 100,
            deposit: 0,
          });
          profile.save();
        }
      } catch (e) {
        await i.editReply("Something went wrong! :( Please retry.");
      } finally {
        if (hasJoined.includes(i.user)) {
          return false;
        }
        if (profile.bananas < bet) {
          interaction.editReply(`${i.user} you don't have enough bananas!`);
        }
        return profile.bananas >= bet;
      }
    };
    const collector = interaction.channel.createMessageComponentCollector({
      filter,
      time: 60000,
    });
    collector.on("collect", async (int) => {
      await int.deferUpdate();
      for (const btn of row.components) {
        if (btn.customId === (int.component as MessageButton).customId) {
          (btn as MessageButton).setDisabled(true).setStyle("SUCCESS");
          hasJoined.push(int.user);
          horses.find((h) => h.name === btn.customId).owner = int.user;
          console.log(horses);
        }
      }

      embed.setDescription(
        `**${horses[0].name} - ${
          horses[0].owner !== null ? horses[0].owner.username : "Nobody"
        } 
        ${horses[0].position}
        
        ${horses[1].name} - ${
          horses[1].owner !== null ? horses[1].owner.username : "Nobody"
        }
        ${horses[1].position}
        
        ${horses[2].name} - ${
          horses[2].owner !== null ? horses[2].owner.username : "Nobody"
        }
        ${horses[2].position} 
        
        ${horses[3].name} - ${
          horses[3].owner !== null ? horses[3].owner.username : "Nobody"
        }
        ${horses[3].position}**`
      );

      await int.editReply({
        embeds: [embed],
        components: [row],
      });
    });
  },
});`

你可以把它变成一个函数:

const displayHorses = (horses: Array<Horse>) => {
  return `**${horses[0].name} - ${
    horses[0].owner !== null ? horses[0].owner.username : "Nobody"
  } 
        ${horses[0].position}
        
        ${horses[1].name} - ${
    horses[1].owner !== null ? horses[1].owner.username : "Nobody"
  }
        ${horses[1].position}
        
        ${horses[2].name} - ${
    horses[2].owner !== null ? horses[2].owner.username : "Nobody"
  }
        ${horses[2].position} 
        
        ${horses[3].name} - ${
    horses[3].owner !== null ? horses[3].owner.username : "Nobody"
  }
        ${horses[3].position}**`;
};

然后每次:

embed.setDescription(displayHorses(horses));

如果你想进一步压缩它,你可以映射马数组。

const displayHorses = (horses: Array<Horse>) => {
  return horses.map(
    ({ name, owner, position }) =>
      `**${name}** - ${owner !== null ? owner.username : "Nobody"}
     ${position}`
  );
};

最后,作为提示,如果您使用的是 14+,您甚至可以进一步将其压缩为:

const displayHorses = (horses: Array<Horse>) => {
  return horses.map(
    ({ name, owner, position }) =>
    `**${name}** - ${owner?.username ?? "Nobody"}
     ${position}`
  );
};