请分享您的想法,参与 2024 年 Clojure 状态调查!

欢迎!请参阅关于页面了解如何使用此工具的更多信息。

0
core.async

我在一个 {{and}} 条件内部有一个 {{go}} 块,其中两个条件从通道中取数据。
当第一个条件返回 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 提出

似乎在这些情况下,strong>和 strong>的使用不正常,不仅仅是与 我在
clojure-1.8.0clojurescript-1.7.228core.async-0.2.374 中进行了测试。
此测试需要配合 nodejsrequest 模块。

(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

评论者:zlorf

bueno,这个问题甚至在没有<!的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中运行这个代码片段时,什么也不会打印出来( comme prévu)。
然而,在ClojureScript中(使用最新的async版本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 报告)
...