如何防止多个CompletableFuture#whenComplete拼接?

huangapple go评论61阅读模式
英文:

How to prevent multiple CompletableFuture#whenComplete concat?

问题

public void resetDailyGambles() {
    synchronized (this) {
        gambleRepository.resetGambles().whenComplete((result, throwable) -> {
            if (throwable != null) {
                Bukkit.broadcastMessage("§cError resetting daily gambles!");
                throwable.printStackTrace();
                return;
            }

            userRepository.findAllByQuery("WHERE last_gamble_reward IS NOT NULL")
                .whenComplete((users, throwable2) -> {
                    if (throwable2 != null)
                        throw new RuntimeException(throwable2);

                    for (User user : users) {
                        GambleReward last = user.getLastGambleReward();
                        Player player = Bukkit.getPlayerExact(user.getName());

                        if (player != null && player.isOnline()) {
                            continue;
                        }

                        PendingGambleClaim pendingGambleClaim = new PendingGambleClaim(UUID.randomUUID(), user.getName(), last, user.getGambleOccasion(), true);
                        pendingGambleRewardRepository.insert(pendingGambleClaim);

                        user.setGambleOccasion(1);
                        user.setLastGambleReward(null);
                        user.setLastGambleState(LastGambleState.NONE);

                        userRepository.update(user);
                    }

                    for (User user : userCache.getAll().values()) {
                        Player player = Bukkit.getPlayerExact(user.getName());

                        GambleReward gambleReward = user.getLastGambleReward();
                        if (gambleReward != null && player != null && player.isOnline()) {
                            user.getLastGambleReward().give(player, user.getGambleOccasion());
                            user.setGambleOccasion(1);
                            user.setLastGambleReward(null);
                            user.getGambles().clear();
                        }
                    }

                    Bukkit.broadcastMessage("§aDaily gambles reset!");
                });
        });
    }
}
英文:

I have this code, and i feel it is so ugly because i'm using multiples whenComplete

public void resetDailyGambles() {
    synchronized (this) {
        gambleRepository.resetGambles().whenComplete((result, throwable) -> {
            if (throwable != null) {
                Bukkit.broadcastMessage("§cError resetting daily gambles!");
                throwable.printStackTrace();
                return;
            }

            userRepository.findAllByQuery("WHERE last_gamble_reward IS NOT NULL")
                .whenComplete((users, throwable2) -> {
                    if (throwable2 != null)
                        throw new RuntimeException(throwable2);

                    for (User user : users) {
                        GambleReward last = user.getLastGambleReward();
                        Player player = Bukkit.getPlayerExact(user.getName());

                        if (player != null && player.isOnline()) {
                            continue;
                        }

                        PendingGambleClaim pendingGambleClaim = new PendingGambleClaim(UUID.randomUUID(), user.getName(), last, user.getGambleOccasion(), true);
                        pendingGambleRewardRepository.insert(pendingGambleClaim);

                        user.setGambleOccasion(1);
                        user.setLastGambleReward(null);
                        user.setLastGambleState(LastGambleState.NONE);

                        userRepository.update(user);
                    }

                    for (User user : userCache.getAll().values()) {
                        Player player = Bukkit.getPlayerExact(user.getName());

                        GambleReward gambleReward = user.getLastGambleReward();
                        if (gambleReward != null && player != null && player.isOnline()) {
                            user.getLastGambleReward().give(player, user.getGambleOccasion());
                            user.setGambleOccasion(1);
                            user.setLastGambleReward(null);
                            user.getGambles().clear();
                        }
                    }

                    Bukkit.broadcastMessage("§aDaily gambles reset!");
                });
        });
    }
}

答案1

得分: 0

你可能正在寻找CompletableFuture.thenCompose。该函数类似于Optional.flatMap,旨在执行链式的CompletableFuture并获取结果的CompletableFuture。一个简要的使用示例:

gambleRepository.resetGambles()
        .thenCompose(resetResult -> userRepository.findAllByQuery("WHERE last_gamble_reward IS NOT NULL")) // 假设findAllByQuery返回CompletableFuture
        .whenComplete((users, throwable) -> /* 你的逻辑 */); // throwable 可能与resetGambles和findAllByQuery调用都相关
英文:

You are probably looking for CompletableFuture.thenCompose. That function is analog of Optional.flatMap, is designed to execute chained completable futures and get resulting CompletableFuture. A brief example of usage:

    gambleRepository.resetGambles()
            .thenCompose(resetResult -> userRepository.findAllByQuery("WHERE last_gamble_reward IS NOT NULL")) // assume findAllByQuery returns CompletableFuture
            .whenComplete((users, throwable) -> /* your logic*/); // throwable could relate both to resetGambles and findAllByQuery call

huangapple
  • 本文由 发表于 2023年6月12日 03:21:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76452172.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定