@@ -5,7 +5,7 @@ module ConcurrentTask exposing
55 , onResponseDecoderFailure, onJsException
66 , mapError, onError
77 , succeed, fail, andThen
8- , fromResult, toResult, andThenDo, return, debug
8+ , fromResult, toResult, andThenDo, finallyDo , return, debug
99 , race
1010 , batch, sequence
1111 , map, andMap, map2, map3, map4, map5
@@ -69,7 +69,7 @@ Lift `UnexpectedError`s into regular task flow.
6969
7070These are some general helpers that can make chaining, combining and debugging tasks more convenient.
7171
72- @docs fromResult, toResult, andThenDo, return, debug
72+ @docs fromResult, toResult, andThenDo, finallyDo, return, debug
7373
7474
7575# Racing Helpers
@@ -696,6 +696,40 @@ andThenDo t2 t1 =
696696 t1 |> andThen ( \ _ -> t2)
697697
698698
699+ {- | Always executes the Task, regardless of whether the previous Task has succeeded or failed.
700+
701+ The behavior is similar to JavaScript's `finally` block in a `try-catch-finally` statement.
702+
703+ This can, for example, be used to ensure that a resource is always released after being locked:
704+
705+ import ConcurrentTask exposing (ConcurrentTask)
706+
707+ lockResource : ConcurrentTask String ()
708+ lockResource =
709+ succeed ()
710+
711+ unlockResource : ConcurrentTask String ()
712+ unlockResource =
713+ succeed ()
714+
715+ performOperation : ConcurrentTask String ()
716+ performOperation =
717+ fail "operation failed"
718+
719+ secureOperation : ConcurrentTask String ()
720+ secureOperation =
721+ lockResource
722+ |> andThenDo performOperation
723+ |> finallyDo unlockResource
724+
725+ -}
726+ finallyDo : ConcurrentTask x a -> ConcurrentTask x b -> ConcurrentTask x a
727+ finallyDo t2 t1 =
728+ t1
729+ |> onError ( \ e -> t2 |> andThenDo ( fail e))
730+ |> andThenDo t2
731+
732+
699733{- | Succeed with a hardcoded value after the previous Task.
700734
701735Maybe you want to do some Tasks on a User but allow it to be chained onwards:
0 commit comments