我正在编写一个 Electron 应用程序,在这个应用程序中我需要与一些 Node.js API 进行交互 - 读取文件、获取目录条目、监听事件。
当然,我可以像编写 JavaScript 一样编写 ClojureScript,但我想知道 ClojureScript 对回调式 API、流、EventEmitter 采取什么,以及我如何以一种方式围绕 node.js API 编写 package 器在 ClojureScript 中看起来并不陌生。
具体来说:
- 如何编写 package 回调式 node.js API 的 API。 (例如,
fs.readdir
) - 如何与类似 EventEmitter 的 API 交互?
- (可能接近第 2 页)我如何使用 node.js 流 API?
最佳答案
根据我的经验,处理这些问题的最简单方法是使用 core.async .
回调样式
例如读取一个目录:
(def fs (js/require "fs"))
(defn read-dir [path]
(let [out (async/chan)]
(.readdir fs path
(fn [err files]
(async/put! (if err err files))
(async/close! out)))
out))
我将结果传递给 channel ,即使该结果是错误的。这样,调用者就可以通过doing来处理错误了。例如:
(let [res (<! (read-dir "."))]
(if (instance? js/Error res)
(throw res)
(do-something res))
在我自己的项目中,我使用 cljs-asynchronize ,它允许您将 NodeJS 回调样式函数转换为 core.async 兼容函数。例如,这与第一个示例相同:
(defn read-dir [path]
(asynchronize
(.readdir fs path ...)))
最后,为了更好地通过 channel 处理错误,我个人找到了"Error Handling with Clojure Async"很有用。因此,您可以像这样编写上面的错误处理代码:
(try
(let [res (<? (read-dir "."))]
(do-something res))
(catch js/Error e
(handle-error e))
流
Stream API 更简单:
(defn create-read-stream [path]
(let [out (async/chan)
stream (.createReadStream fs path)]
(.on stream "close" #(async/close! out))
(.on stream "data" #(async/put! out %))
out))
关于javascript - node.js API 到 ClojureScript 的惯用转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39291779/