我有几个请求处理器,它们都遵循一个类似的模式。
(defn handle-data-1
[req]
{:pre [(some? req)]}
(try
(let [start-date (parse-query-param (-> req :params :start-date))
end-date (parse-query-param (-> req :params :end-date))
data (db/fetch-data-1 start-date end-date)
data-count (count data)]
(log/debugf "data-count=%d start-date=%s end-date=%s" data-count start-date end-date)
(if (pos? data-count)
{:status 200
:body data}
{:status 404}))
(catch Exception e
(let [error-message (.getMessage e)]
(log/errorf "%s" error-message)
{:status 500 :body error-message}))))
(defn handle-data-2
[req]
{:pre [(some? req)]}
(try
(let [limit (Long/valueOf (parse-query-param (-> req :params :limit)))
data (db/fetch-data-2 limit)
data-count (count data)]
(if (pos? data-count)
{:status 200
:body data}
{:status 404}))
(catch Exception e
(let [error-message (.getMessage e)]
(log/errorf "%s" error-message)
{:status 500 :body error-message}))))
(defn handle-data-3
[_]
(try
(let [data (db/fetch-data-3)
data-count (count data)]
(log/debugf "data-count=%d" data-count)
(if (pos? data-count)
{:status 200
:body data}
{:status 404}))
(catch Exception e
(let [error-message (.getMessage e)]
(log/errorf "%s" error-message)
{:status 500 :body error-message}))))
我正在尝试创建一个通用函数,该函数可以被所有的处理函数使用。例如:
(defn try-query [f]
{:pre [(some? f)]}
(try
(let [data (f) ;; <- need to invoke function and store results in data
data-count (count data)]
(if (pos? data-count)
{:status 200
:body data}
{:status 404}))
(catch Exception e
(let [error-message (.getMessage e)]
(log/errorf "%s" error-message)
{:status 500 :body error-message}))))
(defn handle-data-1 [req]
(let [start-date (parse-query-param (-> req :params :start-date))
end-date (parse-query-param (-> req :params :end-date))]
(log/debugf "start-date=%s end-date=%s" start-date end-date)
(try-query (fn [] (db/fetch-data-1 start-date end-date))))) ;;
通用函数需要接受另一个函数(或闭包)作为参数,并且具有可变的arity。我希望这个通用函数可以调用传入的函数,并将其结果存储在变量中。
在 Ruby 中,我可以通过在一个函数中传递一个 lambda,然后在函数中调用它来实现这一点。我不确定如何在 Clojure 中实现这一点。
有任何想法吗?