2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!请查阅 关于 页面,了解更多关于此如何工作的信息。

0 投票
core.async

我在一个 {{go}} 块中有一个 {{and}} 条件,其中两个条件都来自通道。
当第一个条件返回 false 时,我会期望第二个条件根本不会被检查。但实际上它是被检查的。

以下是代码

`
(defn cc [x]
(go

 (println "cc: " x)

x))

(defn foo [x]

(go (when (and (= :ok (<! (cc x)))
               (= :ok (<! (cc 2))))
      (print "after and"))))

(foo 1)
(foo :ok)
`

当运行 {{(foo 1)}}, 我期望只打印 {{cc: 1}},但实际上也打印了 {{cc: 2}}。

仅在 ClojureScript 中发生,不在 Clojure core.async 中发生。

5 个回答

0 投票

评论由:ashercoren

注意:这仅在 ClojureScript 中发生。在 Clojure 中它按预期工作。

也对不起,格式很差。这是我第一次遇到 Jira 问题。

0 投票

评论由:wxlite

这看起来在许多情况下,不仅在与 <! 一同使用时,{{and}} 工作不正常。
我在
clojure-1.8.0clojurescript-1.7.228core.async-0.2.374 上测试了这个。
此测试需要带有 request 模块的 nodejs

(def request (js/require "request"))

现在我尝试向一个不可达的网站发出请求:google
是的,我不能使用 google。

`
(def result-chan (chan))

(request
"http://www.google.com"
(fn [err res body]

(go
  (if (and (not err) (= (.-statusCode res) 200))
    (>! result-chan body)
    (>! result-chan [])))))

`

结果应该是“(链接: )”(请求超时使得“err”非空)

(go (println "结果:" (<! result-chan)))

但实际上我得到

                                    1.   _TypeError: Cannot read property 'statusCode' of undefined ..._ {color}

我已经打印了err,并且我确定在这次情况下它是一个JS对象,不是nil或false。这就是为什么res未定义。
这也意味着and的短路并没有起作用。
要让事情变得正确,请用"if"代替"and"

`
(def result-chan (chan))

(request
"http://www.google.com"
(fn [err res body]

(go
  (if (not err)
    (if (= (.-statusCode res) 200)
      (>! result-chan body)
      (>! result-chan []))
    (>! result-chan [])))))

`

然后重新测试

(go (println "结果:" (<! result-chan)))

现在按预期工作

结果: []

0 投票

评论者:zlorf

well,即使对于没有<!的go-block,这个问题也会发生,这真的很奇怪。或者也是受到影响的。这里有例子

(go (if false (not= 404 (:status (println "SHOULD NOT BE PRINTED 1")))) ; ok (and false (not= 404 (:status (println "SHOULD NOT BE PRINTED 2")))) ; fail (or true (not= 404 (:status (println "SHOULD NOT BE PRINTED 2a")))) ; fail (if false (:status (println "SHOULD NOT BE PRINTED 3"))) ; ok (and false (:status (println "SHOULD NOT BE PRINTED 4"))) ; ok (or true (:status (println "SHOULD NOT BE PRINTED 4a"))) ; ok )

当你在这个Clojure代码片段中运行时,什么都不会打印(如预期)。
然而,在ClojureScript中(使用最新的async版本0.3.443),你会看到{{SHOULD NOT BE PRINTED 2}}和{{2a}}。
有趣的观察:较短的计算(如示例4/4a)表现正常。

就像王兴注意到的:使用if似乎是规避这个错误的可靠方法。

0 投票

评论者:zlorf

我建议将问题标题改为“(CLJS) and/or does not short-circuit in go”

0 投票
参考: https://clojure.atlassian.net/browse/ASYNC-158(由alex+import报告)
...