0

我的 Web 客户端(用 编写cljs)连接到clj需要进行一些第三方 API 调用的后端(用 编写)。它必须在服务器上完成,然后以特定方式转换结果并发送回客户端。

这是我的其中一个网址的处理程序

(defn get-orders [req]
  (let [{:keys [sig uri]} (api-signature :get-orders)]
    (client/get uri
                {:async? true}
                (fn [response] {:body "something"})
                (fn [exception] {:body "error"}))))

它不是返回{:body "something"},而是返回以下错误:

No implementation of method: :render of protocol: #'compojure.response/Renderable found for class: org.apache.http.impl.nio.client.FutureWrapper

我究竟做错了什么?

4

1 回答 1

7

当您指定{:async? true},clj-http.client/get将返回一个未来,这是FutureWrapper您收到的错误消息中的 a 。

因此,如果您不需要异步,请不要使用它。这是一个同步环处理程序的示例,它调用第三方 url 并返回返回的响应。

(defn handler [request]
  (response {:result (client/get "http://example.com")}))

如果您真的需要异步,请使用异步版本的环处理程序。

(defn handler [request respond raise]
  (client/get "http://example.com"
              {:async? true}
              (fn [response] (respond {:body "something"}))
              (fn [exception] (raise {:body "error"}))))

不要忘记配置网络服务器适配器以使用异步处理程序。例如,对于 Jetty,将:async?flag 设置为truelike so

(jetty/run-jetty app {:port 4000 :async? true :join? false})

如果你想同时调用多个第三方 url 并返回一次 web 客户端,使用promise来帮助

(defn handler [request]
  (let [result1 (promise)
        result2 (promise)]
    (client/get "http://example.com/"
                {:async? true}
                (fn [response] (deliver result1 {:success true :body "something"}))
                (fn [exception] (deliver result1 {:success false :body "error"})))
    (client/get "http://example.com/"
                {:async? true}
                (fn [response] (deliver result2 {:success true :body "something"}))
                (fn [exception] (deliver result2 {:success false :body "error"})))
    (cond
      (and (:success @result1)
           (:success @result2))
      (response {:result1 (:body @result1)
                 :result2 (:body @result2)})

      (not (:success @result1))
      (throw (ex-info "fail1" (:body @result1)))

      (not (:success @result2))
      (throw (ex-info "fail2" (:body @result2))))))
于 2017-12-03T04:08:08.977 回答