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 核心异步中不会发生。

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”非nil)

(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
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似乎是避开这个bug的安全方式。

0
by

评论者:zlorf

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

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