首页 > 解决方案 > 如何在 thenable 链上等待第一个到达的结果?

问题描述

我们可以使用Promise.race等待thenable链上第一个到达的结果。Task模块似乎还不支持它,Task.sequence相当于Promise.all

Non-thenable解决方案演示:

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"

标签: taskelmelm-architecture

解决方案


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 =
    ...

推荐阅读