Как дождаться первого прибывшего результата в цепочке?
Мы можем использовать Promise.race, чтобы дождаться первого полученного результата на thenable
цепь. Модуль Task пока не поддерживает его, Task.sequence - это всего лишь эквивалент Promise.all.
Демонстрация нереализуемого решения:
import Process
import Task
init () =
( Nothing, Cmd.batch [ after 2 "2nd", after 1 "1st" ] )
after seconds name =
Process.sleep (1000 * seconds)
|> Task.map (always name)
|> Task.perform Done
type Msg
= Done String
update (Done name) model =
case model of
Nothing ->
( Debug.log name <| Just name, Cmd.none )
_ ->
( Debug.log name model, Cmd.none )
main =
Platform.worker
{ init = init
, update = update
, subscriptions = always Sub.none
}
Запустите его, выведите результат, как ожидается:
1st: Just "1st"
2nd: Just "1st"
1 ответ
Решение
Promise.race
поскольку автономная функция требует поддержания локального состояния для отслеживания того, было ли оно уже разрешено или нет, что, как вы, вероятно, знаете, невозможно в Elm.
Но вы можете сделать то же самое относительно легко, отслеживая состояние в модели самостоятельно. Вот пример использования Maybe
отслеживать, получили ли мы ответ:
type Thing =
...
getThings : String -> Task Never (List Thing)
getThings url =
...
type alias Model =
{ things : Maybe (List Thing) }
type Msg
= GotThings (List Thing)
init =
( { things = Nothing }
, Cmd.batch
[ Task.perform GotThings (getThings "https://a-server.com/things")
, Task.perform GotThings (getThings "https://a-different-server.com/things")
]
)
update msg model =
case msg of
GotThings things ->
case model.things of
Nothing ->
( { things = Just things }, Cmd.none )
Just _ ->
-- if we have already received the things, ignore any subsequent requests
( model, Cmd.none )
view model =
...