Timeouts in Elm
In Elm, we don’t have the concept of timeouts in the same way as Go. However, we can simulate similar behavior using Elm’s Time.every
and Process.sleep
functions. Here’s how we might approach this:
import Browser
import Html exposing (Html, div, text)
import Task
import Time
type Msg
= Tick Time.Posix
| Result1 String
| Result2 String
| Timeout1
| Timeout2
type alias Model =
{ result1 : Maybe String
, result2 : Maybe String
}
init : () -> (Model, Cmd Msg)
init _ =
( { result1 = Nothing, result2 = Nothing }
, Cmd.batch
[ Task.perform Result1 (Process.sleep 2000 |> Task.andThen (\_ -> Task.succeed "result 1"))
, Task.perform Result2 (Process.sleep 2000 |> Task.andThen (\_ -> Task.succeed "result 2"))
, Task.perform (\_ -> Timeout1) (Process.sleep 1000)
, Task.perform (\_ -> Timeout2) (Process.sleep 3000)
]
)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Result1 result ->
( { model | result1 = Just result }, Cmd.none )
Result2 result ->
( { model | result2 = Just result }, Cmd.none )
Timeout1 ->
if model.result1 == Nothing then
( { model | result1 = Just "timeout 1" }, Cmd.none )
else
( model, Cmd.none )
Timeout2 ->
if model.result2 == Nothing then
( { model | result2 = Just "timeout 2" }, Cmd.none )
else
( model, Cmd.none )
Tick _ ->
( model, Cmd.none )
view : Model -> Html Msg
view model =
div []
[ div [] [ text <| "Result 1: " ++ Maybe.withDefault "Waiting..." model.result1 ]
, div [] [ text <| "Result 2: " ++ Maybe.withDefault "Waiting..." model.result2 ]
]
main : Program () Model Msg
main =
Browser.element
{ init = init
, update = update
, view = view
, subscriptions = \_ -> Time.every 1000 Tick
}
In this Elm program:
We define a
Model
that holds the results of our two operations.In the
init
function, we start four tasks:- Two tasks that simulate our “long-running” operations, each taking 2 seconds.
- Two tasks that act as our timeouts, one for 1 second and one for 3 seconds.
In the
update
function:- If a result arrives before its timeout, we store it in the model.
- If a timeout occurs before its result, we store “timeout” as the result.
The
view
function displays the current state of both results.
This Elm program simulates the behavior of the original Go program:
- The first operation will timeout after 1 second.
- The second operation will complete successfully after 2 seconds, before its 3-second timeout.
Running this program would show:
Result 1: timeout 1
Result 2: result 2
Note that Elm’s architecture and concurrency model are quite different from Go’s. In Elm, we’re using the Elm Architecture with its update
function to handle state changes, rather than using channels and goroutines as in Go.