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
“对象”的响应主体?
- 为了测试,将函数的最后一个表达式更改为
(prn (:body response))
prints "false" 但仍然 returns theManyToManyChannel
- 将函数的最后一个表达式更改为
(:body response)
令人惊讶的是 returns 相同而不是“false”。
我该如何继续?
今天是星期六早上,我觉得很懒,所以我没有 运行 这个,但这应该有用:
(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 对于异步操作有点棘手,但这个技巧可能会有所帮助。
我正在尝试使用 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
“对象”的响应主体?
- 为了测试,将函数的最后一个表达式更改为
(prn (:body response))
prints "false" 但仍然 returns theManyToManyChannel
- 将函数的最后一个表达式更改为
(:body response)
令人惊讶的是 returns 相同而不是“false”。
我该如何继续?
今天是星期六早上,我觉得很懒,所以我没有 运行 这个,但这应该有用:
(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 对于异步操作有点棘手,但这个技巧可能会有所帮助。