ClojureScript (nodejs) function that returns the string content of a file

拥有回忆 提交于 2019-12-11 13:01:00

问题


I am trying to make a function that takes a file path and returns its content as a string. Here is my code snippet:

(defn get-string-from-file-path [path]
  (let [fs (node/require "fs") c (chan)]
      (.readFile fs path "utf8" (fn [err data] ((go (>! c (str data))))))
      (go (def r (str (<! c)))) ; is using def correct here?
       r))
  1. Is using def correct/idiomatic on line 4?
  2. After calling this function with a valid file path, I get the following error:

TypeError: (intermediate value)(intermediate value)(intermediate value)(...).call is not a function at repl:99:6 at tryToString (fs.js:414:3) at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:401:12)

Weirdly enough, if I call the function again I get the desired string content of the file! What is going on here?

EDIT: Here is the corrected function:

(defn get-string-channel-from-file-path [path] ; function is now "get string channel" instead of "get string"
  (let [fs (node/require "fs") c (chan)]
      (.readFile fs path "utf8" (fn [err data] (go (>! c data))))
        c)) ; return channel instead of string

回答1:


  1. No, using def anywhere but at the root scope of your source is generally a bad idea and not idiomatic. If you want to create another local variable then another let expression is the way to go.

  2. For why its working sometimes, you are taking an async function and trying to make it synchronous. This is leading to race conditions. Sometimes the File System is returning the file before you return from the function (and that is why works) and sometimes it is not (error).

There are a few options:

  • You can try to make the function synchronous by using node's readFileSync function. That way you can just return what it returns.

  • Instead of trying to extract the data in the go block, you should return the chan you are putting to >! and have the next function get the data from the channel in its own go block <!. This is much more idiomatic than callbacks when using core.async.



来源:https://stackoverflow.com/questions/34557266/clojurescript-nodejs-function-that-returns-the-string-content-of-a-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!