0ui/elm-task-parallel/1.0.0

NOTE: the latest version is 2.0.0

Task.Parallel

This library helps you run tasks in parallel when you only need the results if every task finishes successfully, similar to Promise.all() in Javascript. A good use case is handling the result of multiple HTTP requests.

Task Helpers

attempt2 : (Msg2 x a b -> msg) -> Task x a -> Task x b -> ( State2 a b, Cmd msg )

Attempt two tasks which will send an update when either all tasks finish successfully or one fails. The returned State will be used in your main update function to call update and pass internal messages.

type Msg
    = TaskStateUpdated (Task.Parallel.Msg2 Http.Error String Int)
    | OneTaskFailed Http.Error
    | AllTasksCompleted String Int


doTask : ( Task.Parallel.State2 String Int, Cmd Msg )
doTask =
    attempt2
        TaskStateUpdated
        fetchString
        fetchInt
(Msg3 x a b c -> msg)
-> Task x a
-> Task x b
-> Task x c
-> ( State3 a b c, Cmd msg )
(Msg4 x a b c d -> msg)
-> Task x a
-> Task x b
-> Task x c
-> Task x d
-> ( State4 a b c d, Cmd msg )
(Msg5 x a b c d e -> msg)
-> Task x a
-> Task x b
-> Task x c
-> Task x d
-> Task x e
-> ( State5 a b c d e, Cmd msg )
attemptList : (ListMsg x a -> msg) -> List (Task x a) -> ( ListState a, Cmd msg )

Attempt a list of tasks which will update when all the tasks have finished or when one fails. Similar to a Task.sequence except in parallel.

type Msg
    = DownloadUpdated (ListMsg Http.Error String)
    | DownloadFailed Http.Error
    | DownloadCompleted (List String)


fetchNames : ( ListState String, nextCmd )
fetchNames =
    attemptList DownloadUpdated [ fetchFirstName, fetchSecondName, fetchThirdName ]

Less Common Helpers

attempt : (a -> msg) -> (x -> msg) -> Task x a -> Cmd msg

Attempt a single task. The benefit of this over Task.attempt is that it handles routing the result to the provided success and failure messages. You can reuse those error messages for different tasks if they're handled the same way. Since there are no other tasks, you don't need to manage any additional updates.

type Msg
    = ErrorOcurred Http.Error
    | FetchCompleted MyData


doTask : Cmd Msg
doTask =
    attempt FetchCompleted ErrorOcurred fetchMyData

Update

You will have to pass internal messages and commands along in your update function in order to eventually get your results.

State2 a b
-> Msg2 x a b
-> (a -> b -> msg)
-> (x -> msg)
-> ( State2 a b, Cmd msg )

Handle updates for two tasks by calling update2 inside of your main update function to keep this library's internal state updated. If they have either all finished successfully or one has failed, the corresponding message you provided will be sent to your main update function. Maintain a copy of the returned state to pass in on each subsequent update. This step is required with attempt[n] functions.

type Msg
    = DownloadUpdated (Task.Parallel.Msg2 Http.Error Actor Film)
    | DownloadFailed Http.Error
    | DownloadCompleted Actor Film


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        DownloadUpdated taskMsg ->
            let
                ( nextTaskState, nextCmd ) =
                    Task.Parallel.update2 model.taskState taskMsg DownloadCompleted DownloadFailed
            in
            ( { model | taskState = nextTaskState }, nextCmd )


        DownloadCompleted actor film ->
            ( { model | actor = actor, film = film, Cmd.none )


        DownloadFailed err ->
            ( { model | loadingError = Just err }, Cmd.none )
State3 a b c
-> Msg3 x a b c
-> (a -> b -> c -> msg)
-> (x -> msg)
-> ( State3 a b c, Cmd msg )
State4 a b c d
-> Msg4 x a b c d
-> (a -> b -> c -> d -> msg)
-> (x -> msg)
-> ( State4 a b c d, Cmd msg )
State5 a b c d e
-> Msg5 x a b c d e
-> (a -> b -> c -> d -> e -> msg)
-> (x -> msg)
-> ( State5 a b c d e, Cmd msg )
-> ListMsg x a
-> (List a -> msg)
-> (x -> msg)
-> ( ListState a, Cmd msg )

Call updateList inside of your main update function to check if the tasks have failed or finished. Maintain a copy of the returned state to pass in on each subsequent updateList. This step is required with attemptList.

type Msg
    = DownloadUpdated (Task.Parallel.ListMsg Actor Http.Error)
    | DownloadFailed Http.Error
    | DownloadCompleted (List Actor)


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        DownloadUpdated taskMsg ->
            let
                ( nextTaskState, nextCmd ) =
                    Task.Parallel.updateList model.taskState taskMsg DownloadCompleted DownloadFailed
            in
            ( { model | taskState = nextTaskState }, nextCmd )


        DownloadCompleted actors ->
            ( { model | actorList = actors, Cmd.none )


        DownloadFailed err ->
            ( { model | loadingError = Just err }, Cmd.none )

Types

type State2 a b

Opaque type for storing state of tasks.

type State3 a b c
type State4 a b c d
type State5 a b c d e
type Msg2 x a b

Opaque type for updating state of tasks.

type Msg3 x a b c
type Msg4 x a b c d
type Msg5 x a b c d e
type ListState a

Opaque type for storing state of task lists.

type ListMsg x a

Opaque type for updating state of task lists.