我有一个通道,我将值放入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