所以我对使用 JDA 相当陌生,我只是好奇为什么在不和谐嵌入中没有正确排序,并返回排行榜上的一些值作为不正确的位置。我知道在循环中使用像这样的异步东西可能有点奇怪,但是有没有办法解决它?
case "leaderboard":
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setTitle("Leaderboard");
embedBuilder.setColor(Color.GREEN);
List<Map.Entry<Long, Long>> sortedEntries = new ArrayList<>(LeaderBoardData.loadYamlFile("leaderboard.yml").entrySet());
sortedEntries.sort(Map.Entry.comparingByValue(Comparator.reverseOrder()));
StringBuilder leaderboardMessage = new StringBuilder();
AtomicInteger rank = new AtomicInteger(0);
for (Map.Entry<Long, Long> entry : sortedEntries) {
long userId = entry.getKey();
long score = entry.getValue();
TestBot.jda.retrieveUserById(userId).queue(user -> {
String userName = user != null ? user.getEffectiveName() : "N/A";
leaderboardMessage.append("**").append(rank.getAndIncrement()).append("**. ")
.append(userName)
.append(": ")
.append(score)
.append("\n");
if (rank.get() == 10) {
embedBuilder.setDescription(leaderboardMessage.toString());
event.replyEmbeds(embedBuilder.build()).queue();
}
});
}
break;
我已经调试到我知道 userId long 和 Score long 以正确的顺序打印的程度,并且它应该正确循环,直到 LAMBDA。目前,它打印出这样的内容:
当我希望它是这样的:
由于您在循环内调用
queue()
,因此检索和处理用户的顺序不能保证与 sortedEntries
列表中的顺序匹配。这会导致排行榜中的顺序不正确。
相反,您可以尝试将
queue()
替换为 complete()
,这将中断当前线程,直到该方法检索并返回用户。
虽然通常不建议这样做,但这是绕过该问题的一种方法。
如果您想保持已发送的整个代码的异步行为,您只需在新线程中运行它即可。
总的来说,您还应该确保为您的机器人选择正确的缓存行为。 如果此方法运行得更频繁,您可能只想选择缓存服务器的所有成员。 应该避免在异步回调中使用这样的逻辑。