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/