我有一个函数,它为令牌发出HTTP请求,该请求将在未来的请求中使用.此令牌在未指定的时间内有效,可能需要几个小时左右.
(defn request-app-token
"Request an app token from FB. Useful for app-global actions, such as creating test users."
[client-credentials]
(-> {"client_id" (:client-id client-credentials)
"client_secret" (:client-secret client-credentials)
"grant_type" "client_credentials"}
(form-encode)
((partial str fb-graph-api "/oauth/access_token?"))
(client/get {:throw-entire-message? true})
:body
(json/read-str)
(get "access_token")))
Run Code Online (Sandbox Code Playgroud)
对我而言,这看起来像是memoize的工作:保留令牌的副本并重复使用它,而不是每次需要时都请求新的令牌.
(def get-app-token (memoize request-app-token)) ; So beautiful :D
Run Code Online (Sandbox Code Playgroud)
我只需要处理令牌过期的情况.为此,我将反转控制; 获取需要令牌的函数,尝试使用memoized令牌运行它,如果失败,则使用新令牌再次尝试.
(defn with-app-token [client-credentials f]
(try (f (get-app-token client-credentials))
(catch Exception e ; I know I should be more specific here, I only want to catch HTTP 400 responses
(f (request-app-token client-credentials)))))
Run Code Online (Sandbox Code Playgroud)
这会有点工作,但在第一个令牌到期后,所有后续调用with-app-token都会请求新令牌.我需要一些方法来清除或使memoized返回值无效get-app-token.
我可以编写自己的memoize函数,使用一个invalidate清除特定结果的函数,但我想知道是否已经有语言中的某些内容可以处理这个问题?
clojure.core.memoize有我需要的东西:一个memo-clear!函数.在要求之后[clojure.core.memoize :refer [memo memo-clear!]],解决方案看起来像这样:
(defn request-app-token
"Request an app token from FB. Useful for app-global actions, such as creating test users."
[client-credentials]
(-> {"client_id" (:client-id client-credentials)
"client_secret" (:client-secret client-credentials)
"grant_type" "client_credentials"}
(form-encode)
((partial str fb-graph-api "/oauth/access_token?"))
(client/get {:throw-entire-message? true})
:body
(json/read-str)
(get "access_token")))
(def get-app-token (memo request-app-token))
(defn with-app-token [client-credentials f]
(try (f (get-app-token client-credentials))
(catch Exception e ; I know I should be more specific here, I only want to catch HTTP 400 responses
(memo-clear! get-app-token client-credentials)
(f (get-app-token client-credentials)))))
Run Code Online (Sandbox Code Playgroud)