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
此测试需要带有 nodejsrequest 模块的 request

(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"非nil)

(go (println "result:" (++ 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:" (++ result-chan)))

现在按预期工作

result: []

0

评论者:zlorf

好的,对于没有<!的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中(使用最新的异步版本0.3.443测试),你会看到{{SHOULD NOT BE PRINTED 2}}和{{2a}}。
有趣观察:较短的计算(如示例4/4a)表现正常。

就像Wang Xing注意到的那样:使用if似乎是一种绕过此错误的安全方式。

0

评论者:zlorf

我建议将问题标题更改为“(CLJS) and/or 在 go 中不短路”

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