使用core.async延迟显示http请求微调器的惯用方式

时间:2019-06-02 13:18:33

标签: clojure timeout clojurescript core.async rum

我正在使用ClojureScript + Rum构建一个简单的Web应用程序,该应用程序在多个地方需要使用通过http / get请求从服务器获取的数据来显示UI片段。

通常,我想在数据完全加载之前显示一个微调框。但是我不想立即显示它,因为它可能会忽隐忽现(服务器可以足够快地返回响应),因此理想情况下它应该显示一些延迟(例如300毫秒)。因此,如果浏览器获得更快的响应,则微调器将不会显示。

如何以一种意识形态的core.async方式做到这一点? (请参见下面的尝试)。

在http请求开始时立即开始显示微调框是很简单的:

(ns my.app
    (:require
        ;; -- snip --
        [cljs-http.client :as http]
        [cljs.core.async :as ca]))

(defonce *state (atom {:loading false :data nil}))

(defn get-data! []
  (go
    (swap! *state assoc :loading true)
    (let [response (<! (http/get "/api/data"))
          data (:body response)]
      (swap! *state assoc :loading false :data data))))

;; -- render the data or spinner if :loading --

但是如何延迟显示微调框?我尝试通过将“超时”和“响应”通道“混合”在一起,然后检查从结果通道获得的值来做到这一点。它可以工作,但是代码感觉很笨拙:


(defonce *state (atom {:loading false :data nil}))

(defn timeout-return [out ms val]
  (go
    (<! (ca/timeout ms))
    (ca/put! out val)))

(defn http-get [out uri]
  (go
    (let [response (<! (http/get uri))]
      (ca/put! out response)
      )))

(defn get-data! []
  (go
    (let [t-out (ca/chan)
          resp-out (ca/chan)
          out (ca/chan)
          mix-out (ca/mix out)
          handle-timeout (fn [] (swap! *state assoc :loading true))
          handle-resp (fn [r] (swap! *state assoc :loading false :data (:body r)))]

      (ca/admix mix-out t-out)
      (ca/admix mix-out resp-out)

      (timeout-return t-out 400 :timeout)
      (http-get resp-out "/api/data")

      (let [r (<! out)]
        (if (= :timeout r)
          (do
            (handle-timeout)
            (handle-resp (<! out)))
          (handle-resp r)))
      )))

;; -- render the data or spinner if :loading --

有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

我个人会避免使用core.async,除非您的并发足够复杂,以至于承诺还不够。创建和从标准js承诺不需要担心的渠道中提取和提取大量的费用。

为延迟微调器,我将使用防抖功能。也许这会有所帮助:https://www.martinklepsch.org/posts/simple-debouncing-in-clojurescript.html

否则,您可以在Google上执行反跳操作。

基本上,您想这样做:

  1. 为您的请求做出承诺
  2. 启动反跳任务以:修改状态以指示加载
  3. 根据承诺.finally,取消所有活动的反跳任务并修改状态以指示您不再加载