我有一個通道,我將值放入doseq循環中。如何返回矢量?
此代碼ISBN清單併爲每個ISBN讀取,確實亞馬遜搜索還書的內容,然後調用另一個函數來獲得銜
(def book_channel (chan 10))
我有一個通道,我將值放入doseq循環中。如何返回矢量?
此代碼ISBN清單併爲每個ISBN讀取,確實亞馬遜搜索還書的內容,然後調用另一個函數來獲得銜
(def book_channel (chan 10))
你需要做一些類型的協調,以確定所有工作完成。你可以拉的協調伸到主線程相當容易:
(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
總是產生一個可以放在頻道上的結果,否則循環將永遠等待。
你解決了我所有的問題..非常感謝 – lalakers4life
它完美的作品 – lalakers4life
你可以做一些解釋什麼循環部分呢?特別是計數結果部分。 – lalakers4life
確保您使用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
返回將會有一個確切的項目寫入一個通道。一旦它的輸入通道關閉,將會寫入一個項目。這使整個事物保持異步,它確實需要將代碼放入書通道的代碼關閉該通知,以表示所有書籍都在那裏。
,現在錯誤消失了。但現在我正在打印出一個空的矢量 – lalakers4life
,這幾乎總是意味着將結果放入陳的代碼會拋出一個異常。您並行觸發所有請求,一旦您在生產中獲得此請求並開始在較大的列表中運行它,這將會拋出速率限制異常。在少量批次中完成這些操作是很好的,批次中的每次調用都是在該批次的前一個調用完成後進行的。並在每次通話之間延遲。如果您使用的是emacs,請在緩衝區名稱* nrepl-server your-project-name *中查找錯誤(它不在默認緩衝區列表中,您必須鍵入名稱) –
您應該關閉!完成後將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>)))
此方法的問題在於,一個去做整個工作。我已經進入了doseq內部,這樣多個go可以處理不同的ISBN – lalakers4life
只要您能夠判斷async/into何時能夠產生最終結果,那麼「go」塊的數量並不重要。如果你使用上傳,它會自動關閉!所有項目被複制時的頻道。如果你需要「去」塊來協調並行工作,你應該考慮採用管道功能。看到我的其他答案[這裏](http://stackoverflow.com/a/40615396/6013799) – rmcv
您是否在任何地方關閉book_channel? –
哪裏會(close!book_channel)去?我對此感到困惑。 – lalakers4life
你應該關閉!您完成劑量後book_channelq – rmcv