当前位置: 首页 > 知识库问答 >
问题:

是否可以在Clojure中使一个被memoized函数的值无效?

师野
2023-03-14

我有一个函数,它对一个令牌发出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")))

对我来说,这看起来像是memoize的工作:保留令牌的副本并重用它,而不是每次我需要新的令牌时都请求新的令牌。

  (def get-app-token (memoize request-app-token)) ; So beautiful :D
  (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)))))

这可能会起作用,但在第一个令牌过期后,随后对with-app-token的所有调用都将请求新的令牌。我需要一些方法来清除或使get-app-token的memoized返回值无效。

我可以编写自己的memoize函数,使用一个invalidate函数来清除特定的结果,但是我想知道语言中是否已经有一些东西可以处理这个问题?

共有1个答案

姜淇
2023-03-14

clojure.core.memoize有我需要的东西:一个memo-clear!函数。在需要[clojure.core.memoize:refer[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)))))
 类似资料:
  • 问题内容: 我想使用Streams.intRange(int start,int end,int step)实现反向排序的流。但是,似乎java.util.Streams类不再可用(但是它仍在标准库的rt.jar中)。此方法是在其他类中还是被其他方法替代? 问题答案: 实际上,JDK中再也没有这种方法了。您能获得的下一个最接近的位置是,但是只会一步一步走。 一种解决方案是实施您自己的解决方案。例如

  • 检查第一个数字参数是否可被第二个数字整除。 使用模运算符(%)来检查余数是否等于 0 。 const isDivisible = (dividend, divisor) => dividend % divisor === 0; isDivisible(6, 3); // true

  • 是否可以初始化一个Spring? 例如。 (我正在尝试最后两个场景)

  • 问题内容: 你能 声明这样 的函数吗? 然后像这样 重新声明 它… 这样可以覆盖函数吗? 可以吗 问题答案: 编辑 解决此答案未直接解决原始问题的评论。如果您是通过Google搜索到达的,请从此处开始 有一个名为override_function的函数可以实际使用。但是,由于此函数是Advanced PHP Debugger扩展的一部分,因此很难为生产使用提供参数。因此,我要说“否”,不可能以原始

  • 我有一个通知组件,我有一个超时设置。超时后,我调用。 我想做的是,如果已经超时,我想只呈现任何内容: 问题是: 返回();//这里有一些语法错误