亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在異步執行時停止函數鏈執行的最佳實踐是什么?

在異步執行時停止函數鏈執行的最佳實踐是什么?

三國紛爭 2023-08-23 17:20:56
我這里有這個功能:Function<Integer, Integer> func = (value) -> value + 5;        func = func.andThen((value) -> {            //Imagine that here some code executed and raised an exception, I'm throwing it             //manually just for the sake of this example.            throw new RuntimeException("failed");        });        func = func.andThen((value) -> {            System.out.println("Reached last function !");            return value;        });        executeFunction(func);現在,您可以看到我在第一個 andThen 方法中引發了運行時異常。那是因為我想阻止第二個 andThen 被執行。這是最好的方法嗎?另外,我注意到,如果我在不同的線程(異步)中執行此函數,則異常不會打印在我的控制臺中,并且我想知道異常發生了。private static void executeFunction(Function<Integer, Integer> function) {        CompletableFuture.supplyAsync(() -> function.apply(100));    }在這種情況下,如果我想確保記錄異常,但 andThen 鏈中的下一個函數沒有執行,我應該記錄并拋出異常嗎?這不是一個ati模式嗎?
查看完整描述

3 回答

?
慕尼黑8549860

TA貢獻1818條經驗 獲得超11個贊

實例化和拋出大量異??赡軙兊孟喈敯嘿F,這就是為什么它們應該僅限于特殊情況。相反,您可以使用Optional來控制流:

func = (value) -> Optional.of(value + 5);

func = func.andThen((optionalValue) -> {

? ? // Instead of throwing an exception, return an empty Optional

? ? System.out.println("Log the failure");

? ? return Optional.empty();

});

func = func.andThen((optionalValue) -> {

? ? optionalValue.map((value) -> { // This lambda will only execute if optionalValue is not empty

? ? ? ? System.out.println("Reached last function !");

? ? ? ? return value; // map wraps this in an Optional

? ? });

});

// Finally, unwrap the value. Optional provides a number of ways to do this, depending on how you want to handle failure/empty

func = func.andThen((optional) -> optional.orElse(...));

executeFunction(func);


查看完整回答
反對 回復 2023-08-23
?
冉冉說

TA貢獻1877條經驗 獲得超1個贊

您可以為函數/可運行對象編寫一個包裝器,在任務失敗時記錄并退出。就像這樣:


class Runnables

{

    public static Runnable trying(Runnable... runnables)

    {

        return () ->

        {

            int successes = 0;

            try

            {

                for(Runnable runnable : runnables)

                {

                    runnable.run();

                    successes++;

                }

            }

            catch(Throwable t)

            {

                logger.error("Exception thrown from "+successes+"th runnable: ",t);

            }

        };

    }

}

然后:


private static void executeFunction(Runnable... runnables)

{

    CompletableFuture.supplyAsync(Runnables.trying(runnables));

}


查看完整回答
反對 回復 2023-08-23
?
萬千封印

TA貢獻1891條經驗 獲得超3個贊

您可以通過使用CompletableFuture.thenApply方法來獲得所需的行為。例如:

public class Answer {

? public static void main(String[] args) {

? ? Function<Integer, Integer> fn0 = v -> v + 5;


? ? Function<Integer, Integer> fn1 = v -> {

? ? ? ? throw new RuntimeException("failed");

? ? };


? ? Function<Integer, Integer> fn2 = v -> {

? ? ? ? System.out.println("Reached last function !");

? ? ? ? return v;

? ? };


? ? CompletableFuture.supplyAsync(() -> fn0.apply(100))

? ? ? ? ? ? .thenApply(fn1)

? ? ? ? ? ? .thenApply(fn2)

? ? ? ? ? ? .exceptionally(throwable -> {

? ? ? ? ? ? ? ? // next line prints the exception thrown by fn1, wrapped in java.util.concurrent.CompletionException

? ? ? ? ? ? ? ? System.out.println("Failed with error: " + throwable);?

? ? ? ? ? ? ? ? return 0; // default value, used when exception is thrown

? ? ? ? ? ? });

? }

}

基本上,CompletableFuture鏈將被“開箱即用”的異常中斷,因此不需要額外的處理。


或者,如果您想要更通用的方法:


public class Answer {

? public static void main(String[] args) {

? ? executeAsync(() -> stepOne(100))

? ? ? ? ? ? .thenApply(Answer::stepTwo)

? ? ? ? ? ? .thenApply(Answer::finalStep)

? ? ? ? ? ? .exceptionally(Answer::handleException);

? }


? private static CompletableFuture<Integer> executeAsync(Supplier<Integer> task) {

? ? return CompletableFuture.supplyAsync(task::get);

? }


? private static Integer stepOne(Integer value) {

? ? return value + 5;

? }


? private static Integer stepTwo(Integer value) {

? ? throw new RuntimeException("failed");

? }


? private static Integer finalStep(Integer value) {

? ? System.out.println("Reached last function !");

? ? return value;

? }


? private static Integer handleException(Throwable throwable) {

? ? // next line prints the exception thrown by any step before, wrapped in java.util.concurrent.CompletionException

? ? System.out.println("Failed with error: " + throwable);

? ? return 0; // default value

? }

筆記:


使用thenApply您可以根據需要鏈接任意數量的函數調用


在最后一個示例中,同一類中的方法可以替換為其他類中的方法(不一定是靜態類)


查看完整回答
反對 回復 2023-08-23
  • 3 回答
  • 0 關注
  • 205 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號