2016-04-17 9 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を使用すると、実行順序は右から左になります。この矛盾はどのように妥当ですか?クローージャーブートのタスクの実行順序が変わるのはなぜですか?

答えて

6

compを起動タスクで使用すると、それらは作成される裸のロジックではないが、各起動タスクは後で呼び出される関数を返し、その関数は渡される別の関数をラップするそれは(リングミドルウェアのように)。プレーンな機能を備えた

が、それはこのように動作します:ブートタスクで

(inc (dec n))

がリングミドルウェアに似ています:

(comp inc dec)

は、以下のんの関数を生成します。各タスクは、パイプラインから次のハンドラをラップする別の関数を返す関数です。それは(文字通り、それは読みやすさのために簡略化されていますではない)というように動作します:

(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)によって生成される関数に渡されるため、w 1つを(task2)からラップしてください(そして、1の印刷後に呼び出してください)。

起動タスクの詳細については、its wikiで読むことができます。 ring middlewareを読むことも便利です。

+0

ありがとうございました!あなたの説明は素晴らしいです! –

+0

"これは実行順序です"と答えてください。私はまだ分かりませんが、私は '(comp(task1)(task2))'は '(task1(task2))'を意味すると思いますか? –

関連する問題