Concurrency 未来永远不会解决问题,也不会兑现承诺
我在读一本书来教自己Clojure,这本书叫做Clojure,是为勇敢和真诚的人写的。第9章介绍了基本的并发编程,包括延迟、未来和承诺。本章末尾的第一个练习说明: “编写一个函数,将字符串作为参数,并使用slurp函数在Bing和Google上搜索它。您的函数应返回搜索返回的第一页的HTML” 我的解决办法如下:Concurrency 未来永远不会解决问题,也不会兑现承诺,concurrency,clojure,parallel-processing,functional-programming,lisp,Concurrency,Clojure,Parallel Processing,Functional Programming,Lisp,我在读一本书来教自己Clojure,这本书叫做Clojure,是为勇敢和真诚的人写的。第9章介绍了基本的并发编程,包括延迟、未来和承诺。本章末尾的第一个练习说明: “编写一个函数,将字符串作为参数,并使用slurp函数在Bing和Google上搜索它。您的函数应返回搜索返回的第一页的HTML” 我的解决办法如下: (defn search-bing-google [search-term] (let [search-results (promise)] (futu
(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))
(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-bing-google "clojure")
(search "clojure" :bing :google)
第二项工作是:
“更新您的函数,以便使用由搜索引擎组成的第二个参数。”
我试图编辑我的第一个解决方案以满足新的参数要求,如下所示:
(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))
(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-bing-google "clojure")
(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))
因为
map
会导致延迟求值,所以需要一些东西来实现它。在您的代码中,没有任何东西可以做到这一点,因此未来永远不会真正创建。不只是映射,而是执行以下操作:
(dorun (map ...
我没有在地图上使用
dorun
。相反,我使用doseq
来迭代我的关键字列表。但感谢您让我走上了使用dorun
、doall
、doseq
等进行强制求值的道路。