2016-11-15 12 views
2

私はdoseqループの中に値を入れているチャンネルがあります。ベクターを返すにはどうしたらいいですか?

このコードは、ISBNコードのリストから、各ISBNために読み込み本の内容を返すためにアマゾンの検索を行い、その後、あなたが使用してくださいタイトルやランク

(def book_channel (chan 10)) 
+0

book_channelをどこかで終了していますか? –

+0

どこで(close!book_channel)行くのですか?私はそれを混乱させる。 – lalakers4life

+0

あなたは閉じる必要があります!あなたがdoseqを完了した後のbook_channel – 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/intoではなくclojure.core.async/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正確に一つの項目がそれに書かれていますチャネルを返します。その1つの項目は入力チャンネルが終了すると書き込まれます。これはすべてのことを非同期に保ち、すべての本がそこにあることを知らせるために、コードをブックチャンネルに入れることが必要です。

+0

よくエラーが消えました。しかし、今私は空のベクトル – lalakers4life

+0

を印刷しています。ほとんどの場合、その結果をchanに入れるコードは例外をスローしています。すべてのリクエストを並行して実行していますが、これを実行するとレート制限の例外が発生し、大きなリストで実行するようになります。少数のバッチでそれらを実行すると良いです。そのバッチからの前回の呼び出しが終了した後にバッチ内の各呼び出しが行われます。各呼び出しの間に遅延を置く。 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

この方法の問題は、 1つは仕事全体をやって行く。私はdoseqの中に入っていたので、複数のgoが別のISBNを扱うことができるようになった。 – lalakers4life

+0

async/intoが最終結果を生成することができる限り、「go」ブロックの数は重要ではない。あなたがon-chanを使用すると、自動的に閉じます!すべての項目がコピーされるときのチャンネル。コーディネートされた方法で作業を並列化するために "go"ブロックが必要な場合は、パイプライン機能の採用を検討する必要があります。私の他の答えを参照してください[こちら](http://stackoverflow.com/a/40615396/6013799) – rmcv