我正在通过Java Discord API设计一个Discord机器人。我得到了一个服务器点系统,当用户在频道中发言时记录点。服务器点存储在一个HashMap<String, Long> points
中,它使用用户的ID作为键,点作为值。我想要一个命令/ranking
来显示点的排名,下面是我的代码:
List<userAndBlocks> sorted = new ArrayList<>(points.size());
JDA jda = event.getJDA();
points.forEach((userID, blocks) ->
{
User user = jda.getUserById(userID);
if (user == null)
jda.retrieveUserById(userID).queue(
user1 -> sorted.add(new UserAndBlocks(user1, blocks)),
throwable -> sorted.add(new UserAndBlocks(jda.getSelfUser(), 0L)));
else
sorted.add(new UserAndBlocks(user, blocks));
});
try
{
Thread.sleep(1000L); //wait for retrieveUserById
}
catch (InterruptedException e)
{
e.printStackTrace();
System.out.print('\u0007');
FileHandle.log(e);
System.exit(1);
}
sorted.sort((user1, user2) ->
{
return Long.compare(user2.blocks, user1.blocks);
});
对于UserAndBlocks
,它是一个记录:
public record UserAndBlocks(User user, long blocks) {}
我知道getUserById
只能获取缓存的用户,所以我请求ChatGPT,它告诉我使用retrieveUserById
。如您所见,我遍历了整个Map,使用retrieveUserById
从用户ID获取用户,并通过Thread.sleep(1000L)
使主线程休眠。为retrieveUserById
方法争取一些时间。但是列表仍然没有包括我在Map中确定的所有用户。我该怎么做呢?
1条答案
按热度按时间ccrfmcuu1#
JDA应该使用回调策略异步使用。
这意味着您不应该阻塞任何线程和等待,而是应该在事情完成后立即处理。
在您的例子中,我看到您执行了多个rest操作,要在所有这些操作完成后执行某个操作,请使用
RestAction.allOf()
获取一个RestAction,该操作在所有作业完成后执行。此外,
retrieveUserById
实际上将首先检查缓存,只有在用户尚未缓存时才加载用户,而不是执行逻辑,首先从缓存中获取用户,然后检查是否加载了用户。