2016-04-17 3 views
1
(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 на анонимных функциях, выполнение выполняется справа налево. Как это несоответствие разумно?Почему изменяется порядок выполнения задач в загрузке clojure?

ответ

6

Причина, по которой эта разница заключается в том, что при использовании 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).

Подробнее о анатомии задач загрузки вы можете узнать в its wiki. Полезно также читать по адресу ring middleware.

+0

Спасибо! Ваше объяснение великолепен! –

+0

Не могли бы вы изменить свой ответ, чтобы начать с «это порядок исполнения»? Я все еще не уверен, но я думаю '(comp (task1) (task2))' означает '(task1 (task2))'? –