2016-11-15 87 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