为什么 clojure 引导中任务的执行顺序会发生变化


(deftask test1 "first test task" [] (print "1") identity)
(deftask test2 "second test task" [] (print "2") identity)
(boot (comp (test1) (test2)))
=> 12nil
(boot (comp (fn [x] (print "1") identity) (fn [x] (print "2") identity)))
=> 21nil

如果我在任务上使用comp,则执行顺序是从左到右。如果我在匿名函数上使用comp,则执行顺序是从右到左。这种不一致如何合理?

这种差异的原因是,当您将comp与引导任务一起使用时,它们不是组合的裸逻辑,而是每个引导任务返回一个稍后将调用的函数,并且该函数包装另一个传递给它的函数(如在环中间件中(。

使用普通函数,它的工作原理如下:

(comp inc dec)

生成一个函数,该函数执行以下操作:

(inc (dec n))

在引导中,任务类似于环形中间件。每个任务都是一个函数,它返回另一个函数,该函数将从管道包装下一个处理程序。它的工作原理是这样的(不是字面意思,为了可读性而简化了(:

(defn task1 []
  (fn [next-handler]
    (fn [fileset]
      (print 1) ;; do something in task1
      (next-handler fileset))) ;; and call wrapped handler
(defn task2 []
  (fn [next-handler]
    (fn [fileset]
      (print 2) ;; do something in task1
      (next-handler fileset)))) ;; and call wrapped handler

因此,当您这样做时:

(comp (task1) (task2))

并执行这样的组合任务,它就像是:

(fn [fileset1]
  (print 1)
  ((fn [fileset2]
     (print 2)
     (next-handler fileset2))
   fileset1))

因为由(task2)生成的函数将被传递给(task1)生成的函数,该函数将包装来自(task2)的函数(并在打印1后调用它(。

您可以在其 wiki 中阅读有关启动任务剖析的更多信息。在环形中间件上阅读也可能很有用。

相关内容

  • 没有找到相关文章

最新更新