Clojure 如何返回向量?

Clojure 如何返回向量?,clojure,Clojure,我有一个通道,我将值放入doseq循环中 这段代码从一个isbn列表中读取,对于每个isbn,执行amazon搜索以返回一本书的内容,然后调用另一个函数以获取标题和排名 (def book_channel (chan 10)) 确保使用clojure.core.async/into而不是clojure.core/into。以下是一个从采集到频道再返回采集的往返示例: user> (require '[clojure.core.async :as async :refer [<! &

我有一个通道,我将值放入doseq循环中

这段代码从一个isbn列表中读取,对于每个isbn,执行amazon搜索以返回一本书的内容,然后调用另一个函数以获取标题和排名

(def book_channel (chan 10))

确保使用
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]
user>(需要“[clojure.core.async:as async:refere[!!>!chan go]]”)
无
用户>(def book chan(异步/到chan[:book1:book2:book3]))
#'用户/书籍
用户>(

clojure.core.async/into
返回一个通道,该通道将恰好写入一个项目。该项目将在其输入通道关闭后写入。这将保持整个项目的异步,并且确实需要将内容放入书籍通道的代码关闭chan,以表示所有书籍都在那里。

您应该d关闭!完成将内容推入book_通道后。根据async/into文档-“ch必须在into生成结果之前关闭。”

(让[book>(chan)]
(去
(doseq[e(范围8)]
(>!book>e))
(关闭!书本>))
()))
或者,您可以使用async/On-chan为您关闭通道:

(let [book> (chan)]
  (async/onto-chan book> (range 8))
  (<!! (async/into [] book>)))
(让[book>(chan)]
(异步/上禅书>(范围8))
()))

您需要进行某种类型的协调,以确定所有工作何时完成。您可以相当轻松地将该协调引入到主线程中:

(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)))))))
(def book_频道(chan 10))
(defn并发性测试)
[ISBN列表]
(doseq[isbn列表]
(go(>!book_频道)
(获取isbn的标题和排名)
(亚马逊搜索isbn()()))
(prn(循环[结果[]]
(如果(=(计数结果)(计数列表)
后果
(重现(联合结果)(

在这里,我使用了一个循环,不断等待结果并将它们添加到向量中,直到我们得到与isbn一样多的结果。您需要确保
get\u title\u和\u rank\u for_one\u isbn
始终生成一个可以放在频道上的结果,否则循环将永远等待。

您是否关闭了book\u频道?在哪里ld(关闭!预订频道)走?我搞糊涂了。你应该关上!看完书后再关上图书频道doseq@rmcv我试着这样做,但没有成功。我更新了我的问题和我现在所拥有的。现在错误消失了。但现在我打印出一个空向量,这几乎总是意味着将结果放入chan的代码抛出了一个异常。您将并行触发所有请求,一旦您在生产环境中得到这些请求并开始在更大的列表上运行它,将引发速率限制异常。最好在少量批中执行这些请求,其中批中的每个调用都是在该批的上一次调用完成后进行的。并在每次调用之间设置一个延迟。如果您使用的是emacs在缓冲区名称nrepl服务器中查找您的项目名称以查找错误(它不在默认缓冲区列表中,您必须键入名称)。这种方法的问题是整个工作只有一个go。我已经进入了doseq,以便多个go可以处理不同的ISBN“go”编号块不重要,只要你能告诉async/into何时能产生最终结果。如果你使用On-chan,它会在复制所有项目时自动关闭通道。如果你需要“go”块以并行的方式并行工作,你应该考虑采用流水线函数。看看我的另一个答案,你能对循环部分做些什么解释吗?特别是计数结果部分。用一点解释来编辑答案。哦,我知道它在做什么。非常整洁。
(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)))))))