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 [])))))

`

结果应该是 "(link: )" (请求将超时使 "err" 非空)

(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)))

现在按预期工作。

结果:[]

0
by

评论由:zlorf 添加。

好,即使对于没有 <! 的 go-block 也会出现这个问题,这真的很奇怪。"or" 也受影响。这里有一个例子

(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)表现正常。

正如 Wang Xing 所注意到的:使用 if 似乎是一种避免这个错误的合理方法。

0
by

评论由:zlorf 添加。

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

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