【发布时间】:2017-05-31 14:12:51
【问题描述】:
我正在阅读一本书来自学 Clojure,名为 Clojure for the Brave and True。第 9 章介绍了基本的并发编程,包括延迟、期货和承诺。本章末尾的第一个练习指出:
“编写一个将字符串作为参数的函数,并使用 slurp 函数在 Bing 和 Google 上搜索它。你的函数应该返回搜索返回的第一页的 HTML”
我的解决方法如下:
(defn search-bing-google
[search-term]
(let [search-results (promise)]
(future (deliver search-results
(slurp (str "https://www.bing.com/search?q%3D" search-term))))
(future (deliver search-results
(slurp (str "https://www.google.com/search?q%3D" search-term))))
@search-results))
并且可以这样调用:
(search-bing-google "clojure")
第二个练习如下:
“更新您的函数,使其接受包含要使用的搜索引擎的第二个参数。”
我尝试编辑我的第一个解决方案以满足新的参数要求,如下所示:
(def search-engines
{:bing "https://www.bing.com/"
:google "https://www.google.com/"})
(defn search
[search-term & engines]
(let [results (promise)]
(map #(future (deliver results
(slurp (str (% search-engines)
"search?q%3D"
search-term)))) engines)
@results))
并且可以这样调用:
(search "clojure" :bing :google)
然而,这个实现与它的前身不同。就好像由于第二个实现中的“地图”而从未调用过 slurp。当我在 REPL 中加载并执行它时,谁能帮我弄清楚是什么导致它挂起?
编辑:
根据下面 Josh 的回答,我想出了以下解决方案,不再使用 doseq 而不是 dorun 和 map 挂起:
(def search-engines
{:bing "https://www.bing.com/"
:google "https://www.google.com/"})
(defn search
[search-term & engines]
(let [results (promise)]
(doseq [engine engines]
(future (deliver results
(slurp (str (engine search-engines)
"search?q%3D"
search-term)))))
@results))
【问题讨论】:
标签: concurrency clojure parallel-processing functional-programming lisp