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

现在工作如预期。

结果:[]

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

就像王兴注意到的:使用 if 似乎是一种避免这个错误的保险方法。

0 投票
by

评论者:zlorf

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

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