ClojureScript:如何访问(不仅仅是打印)HTTP GET 请求的结果

ClojureScript: How to access (not just print) the result of an HTTP GET request

我正在尝试使用 Clojure(服务器)和 ClojureScript(客户端)构建一个简单的客户端-服务器系统。

服务器端正常(浏览器控制台上一切都是绿色的,没有CORS问题等);响应是纯文本(“true”或“false”)。在客户端,我基本上使用 official cljs-http website

中包含的功能
(defn get-request [str1 str2]
(go (let [response (<! (http/get "http://localhost:3000"
                                 {:query-params {"str1" str1
                                                 "str2" str2}}))]
  (prn response))))

运行 REPL 上的这个函数表明一切正常,异步通道中出现了类似地图的东西

cljs.user=> (b/get-request "foo" "bar")
#object[cljs.core.async.impl.channels.ManyToManyChannel]         ;; the result
cljs.user=> {:status 200, :success true, :body "false", [...]}   ;; output of `prn`

我的问题是:我怎样才能真正得到那个ManyToManyChannel“对象”的响应主体?

我该如何继续?

今天是星期六早上,我觉得很懒,所以我没有 运行 这个,但这应该有用:

(defn get-request [str1 str2]
  (go (<! (http/get "http://localhost:3000"
                    {:query-params {"str1" str1
                                    "str2" str2}}))))


(defn read-response [response-chan]
  (go (let [resp (<! response-chan)]
        (prn resp))))  ; <- the only place where you can "touch" resp!

(read-response (get-request "a" "b"))

go 块 returns 一个通道,它将接收您在请求响应中放入其中的结果(从原始 go 块返回的表单)。

读取函数接受一个通道并从中读取,最后一种形式只调用第二个函数,调用第一个函数的结果。

请记住,渠道是第一个 class 构造,您可以传递它们,与多个消费者共享它们,等等。

您无法以同步方式访问 async 操作(例如 go)的结果。所以获得实际响应的唯一方法是在异步回调中。

REPL 中获取结果有点棘手。您可以将它存储在一个原子中,并在操作完成后从原子中访问它。

(def result-ref (atom nil))

(defn into-ref [chan]
  (go (reset! result-ref (<! chan))))

(into-ref
  (http/get "http://localhost:3000"
    {:query-params
     {"str1" str1
      "str2" str2}}))

@result-ref

当然,您只能在操作实际完成后才能访问结果。 REPL 对于异步操作有点棘手,但这个技巧可能会有所帮助。