javascript - 迭代回调 hell (ClojureScript 中)

标签 javascript node.js clojure clojurescript

1 有问题的 JavaScript 函数

我正在处理 JS 中一个非常有问题的函数,它会多次调用回调函数。特别是,该函数接受 yaml 字符串,并为字符串中找到的每个个 yaml 文档运行回调函数:

var yaml = require('js-yaml');

yaml.safeLoadAll(data, function (doc) {
  console.log(doc);
  });

因此,如果 data 包含 2 个 yaml 文档,那么我们将在控制台中看到 2 个日志。

2 在 ClojureScript 中处理它

假设 string未知数量的 yaml 文档。我想使用 core.async channel 将每个文档放入 JavaScript 数组中。

首先,我创建一个函数,将每个 yaml 文档塞入一个 channel :

(defn yaml-string->yaml-chan [string]
  (let [c (chan)]
    (go 
      (.safeLoadAll 
       yaml
       string 
      (fn [current-yaml-object] 
        (go 
          (>! c current-yaml-object)
          ;(close! c) ; cant close here or we only get one doc!
        )
      ))  
    ) c ; here we return the channel
  )
)

然后我创建一个函数,从 channel 中吸收每个 yaml 文档并将它们粘贴到 JavaScript 数组中(封装在另一个 channel 中)。

(defn yaml-chan->array-chan [c]
  (let [arr (js/Array.) arr-chan (chan) a (atom true)]
    (go
      (reset! a (<! c))
      (while (not-nil? @a)
    (.push arr @a)
    (reset! a (<! c))
      )
      (>! arr-chan arr)
    ) arr-chan
  )
)

然后我尝试执行结果:

(go (println <! (yaml-chan->yaml-array-chan (yaml-string->yaml-chan string)))

我得到的只是 #object[cljs.core.async.impl.channels.ManyToManyChannel] :( 我认为这是因为我从未关闭过 yaml 对象的原始 channel 。但是我如何使用迭代回调函数执行此操作?在哪里以及如何关闭该 channel ?

最佳答案

我认为 core.async 在这种情况下不会有太大帮助。这对于普通的 JavaScript 来说也是很困难的。只要有更多文档要加载,safeLoadAll 就会触发回调。除了使用某种不稳定的超时检查之外,没有办法知道它是否完成(这不能保证所有内容都已加载,只是在时间阈值内没有发生任何事件)。

如果您不需要将所有文档收集到一个数组中,那么您可以使用 core.async channel 处理来处理每个结果。如果您确实需要一个数组,那么您应该找到另一种方法(循环所有文档并单独加载它们),以便您可以确定所有文件加载何时完成。

关于javascript - 迭代回调 hell (ClojureScript 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34571647/

相关文章:

javascript - 在函数中作为参数传递时无法设置 css 样式

javascript - Vuejs IF 语句

javascript - 使用 fields 参数查询 FB Graph API 提要?

javascript - 客户端重新加载/离开页面后 Socket.io 服务器崩溃

java - Clojure 编译器如何生成 JVM 字节码?

javascript - jquery mouseover动态p标签扩展

node.js - 终止 ExpressJS 请求

javascript - 未知的 Twitter API 问题

loops - Clojure - 循环变量 - 不变性

ruby - 无法启动黎曼健康状况