2
我正在读一本书来教自己Clojure称为Clojure的勇敢和真实。第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)
但是这种实现挂起不像它的前身。它好像在第二次实现中由于“映射”而从不被调用。任何人都可以帮我弄清楚,当我在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))
我没有在地图上使用'dorun'。相反,我使用'doseq'来迭代关键字列表。但是,谢谢你让我在“dorun”,“doall”,“doseq”等方面进行强制评估。 – webermaster