【问题标题】:When do side effects happen?副作用何时发生?
【发布时间】:2015-04-12 22:17:59
【问题描述】:

我正在构建一个阻止 HTTP 调用的应用。我想在阻塞之前打印一些东西,然后在阻塞调用完成后继续打印一些东西。我的第一个挑战就是这样做

(print "Processing " item-hash "...")
(query-item item-hash)
(Thread/sleep 10000)
(println "Done")))

睡眠只是为了让它慢下来,以 100% 确定它会做它应该做的事情。

据我了解,它应该打印消息,启动query-item,然后休眠10 秒,然后打印Done。但目前它会等到整个父 sexpr 完成并在此之后打印(当所有阻塞调用完成时打印整行。

整个主要供参考

(defn -main [& echo]
  (map
    (fn [url]
      (let [item-hash (market-listing-url-to-hash-name url)]
        (print "Processing " item-hash "...")
        (query-item item-hash)
        (Thread/sleep 10000)
        (println "Done")))

    (collect-urls 1)))

谢谢

【问题讨论】:

  • 为什么放慢速度可以确保它完成了它应该做的事情?另外,map 很懒,你想要 pmap 吗?
  • 查询项现在很快,所以我不完全确定它是否先打印“正在处理...”,然后再打印“完成”。感谢您提出 pmap 建议,但我无法并行执行。 query-item 正在访问每秒只允许很少请求的第 3 方 HTTP API。经过一番摸索,我发现如果我使用 (println) 而不是 (print),它会按预期工作。输出缓冲区可能会在换行符上刷新?

标签: clojure functional-programming


【解决方案1】:

显然print 不会自动将缓冲区刷新到屏幕上。在第一个 print 之后添加 (flush) 可以修复它。 println 自行刷新。

源代码:println 调用具有(flush) 作为副作用之一的prn 函数prn

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    • 2012-07-10
    相关资源
    最近更新 更多