比较和设置的懒惰评估



我正在尝试实现一个get-database函数,该函数在第一次调用Monger时从Monger检索数据库引用,记住原子中的值,并在随后的调用中直接返回。我当前的代码如下:

(def database (atom nil))
(defn get-database
  []
  (compare-and-set! database nil
    (let [db (:db (mg/connect-via-uri (System/getenv "MONGOLAB_URI")))] db))
  @database)

问题是,即使compare-and-set!返回false(即database不是nil),let子句似乎也会被求值。有没有什么方法可以让它进行懒惰的评估,这样我就不会因为检索Monger连接而受到惩罚,或者这种方法从根本上被误导了?

这里的问题是compare-and-set!是一个函数,因此对其求值将在调用函数之前对所有参数进行求值。

对于缓存和重新使用一些昂贵的计算值的用例,我采用的典型方法是使用delay:

获取一组表达式并生成一个Delay对象,该对象将仅在第一次强制(使用force或deref/@)时调用主体,并且将缓存结果并在所有后续部队中返回电话。也看到了——实现了吗?

在您的情况下:

(def database (delay (:db (mg/connect-via-uri (System/getenv "MONGOLAB_URI")))))

现在,只要您想在任何时候获得对数据库的引用,就可以说@database,并且在您的代码第一次实际导致延迟被取消引用时,连接就会被初始化。如果愿意的话,可以将调用封装在get-database函数中以取消引用延迟,但这不是必须的。

相关内容

  • 没有找到相关文章

最新更新