2016-11-15 118 views
2

我有一個通道,我將值放入doseq循環中。如何返回矢量?

此代碼ISBN清單併爲每個ISBN讀取,確實亞馬遜搜索還書的內容,然後調用另一個函數來獲得銜

(def book_channel (chan 10)) 
+0

您是否在任何地方關閉book_channel? –

+0

哪裏會(close!book_channel)去?我對此感到困惑。 – lalakers4life

+0

你應該關閉!您完成劑量後book_channelq – rmcv

回答

1

你需要做一些類型的協調,以確定所有工作完成。你可以拉的協調伸到主線程相當容易:

(def book_channel (chan 10)) 
(defn concurrency_test 
    [list_of_isbns] 
    (doseq [isbn list_of_isbns] 
    (go (>! book_channel 
      (get_title_and_rank_for_one_isbn 
       (amazon_search isbn))))) 
    (prn (loop [results []] 
       (if (= (count results) (count list_of_isbns)) 
        results 
        (recur (conj results (<!! book_channel))))))) 

在這裏,我用了一個循環,一直等待結果,並將它們添加到載體,直到我們有儘可能多的結果,因爲我們做的ISBN。你需要確保get_title_and_rank_for_one_isbn總是產生一個可以放在頻道上的結果,否則循環將永遠等待。

+0

你解決了我所有的問題..非常感謝 – lalakers4life

+0

它完美的作品 – lalakers4life

+0

你可以做一些解釋什麼循環部分呢?特別是計數結果部分。 – lalakers4life

2

確保您使用clojure.core.async/into而不是clojure.core/into。下面是從收集往返於海峽的一個例子,回到集合:

user> (require '[clojure.core.async :as async :refer [<! <!! >!! >! chan go]]) 
nil 

user> (def book-chan (async/to-chan [:book1 :book2 :book3])) 
#'user/book-chan 

user> (<!! (clojure.core.async/into [] book-chan)) 
[:book1 :book2 :book3] 

clojure.core.async/into返回將會有一個確切的項目寫入一個通道。一旦它的輸入通道關閉,將會寫入一個項目。這使整個事物保持異步,它確實需要將代碼放入書通道的代碼關閉該通知,以表示所有書籍都在那裏。

+0

,現在錯誤消失了。但現在我正在打印出一個空的矢量 – lalakers4life

+0

,這幾乎總是意味着將結果放入陳的代碼會拋出一個異常。您並行觸發所有請求,一旦您在生產中獲得此請求並開始在較大的列表中運行它,這將會拋出速率限制異常。在少量批次中完成這些操作是很好的,批次中的每次調用都是在該批次的前一個調用完成後進行的。並在每次通話之間延遲。如果您使用的是emacs,請在緩衝區名稱* nrepl-server your-project-name *中查找錯誤(它不在默認緩衝區列表中,您必須鍵入名稱) –

1

您應該關閉!完成後將book_channel推入其中。每個異步/進入文檔 - 「ch必須先關閉才能生成結果。」

(let [book> (chan)] 
    (go 
    (doseq [e (range 8)] 
     (>! book> e)) 
    (close! book>)) 
    (<!! (async/into [] book>))) 

或者,你可以使用異步/到瓚將關閉通道爲您提供:

(let [book> (chan)] 
    (async/onto-chan book> (range 8)) 
    (<!! (async/into [] book>))) 
+0

此方法的問題在於,一個去做整個工作。我已經進入了doseq內部,這樣多個go可以處理不同的ISBN – lalakers4life

+0

只要您能夠判斷async/into何時能夠產生最終結果,那麼「go」塊的數量並不重要。如果你使用上傳,它會自動關閉!所有項目被複制時的頻道。如果你需要「去」塊來協調並行工作,你應該考慮採用管道功能。看到我的其他答案[這裏](http://stackoverflow.com/a/40615396/6013799) – rmcv