如何 return FileReader 的结果。在 clojurescript 中
How to return the result of FileReader. in clojurescript
我有一个使用 js/FileReader.
读取文件的函数:
(defn read-file [file]
(let [js-file-reader (js/FileReader.)]
(set! (.-onload js-file-reader)
(fn [evt]
(let [result (-> evt .-target .-result)
array (js/Uint8Array. result)]
{:content array}))) ; <- This is the value that 'read-file' should return
(.readAsArrayBuffer js-file-reader file)))
问题是我想return.-onload
方法的值FileReader
,但我只得到(当然)[=的值16=] 自然是 undefined
.
非常感谢!
编辑
在尝试 Martin Půda 的回答后,我认为问题与异步的事情有关。我测试了这段代码:
(defn read-file [file]
(let [js-file-reader (js/FileReader.)
reading-result (atom)
done? (atom false)]
(set! (.-onload js-file-reader)
(fn [evt]
(let [result (-> evt .-target .-result)
array (js/Uint8Array. result)]
(reset! reading-result {:content array})
(reset! done? true)
(js/console.log "in: " (:content @reading-result)))))
(.readAsArrayBuffer js-file-reader file)
;; (while (not @done?) (js/console.log (.-readyState js-file-reader)))
(js/console.log "out: " @reading-result)
@reading-result))
我得到 first out: undefined
的日志,然后 in:
的日志(与期望的结果)。
当我取消对行 (while...)
的注释时,我得到了 1
的无限循环...所以我认为该函数从未注意到 FileReader
已完成。 ..我不知道怎么解决这个问题...
试试这个:
(defn read-file [file]
(let [js-file-reader (js/FileReader.)
reading-result (atom)]
(set! (.-onload js-file-reader)
(fn [evt]
(let [result (-> evt .-target .-result)
array (js/Uint8Array. result)]
(reset! reading-result {:content array}))))
(.readAsArrayBuffer js-file-reader file)
@reading-result))
编辑: 参见 HTML5 FileReader how to return result?- 是的,它是异步的。我看到两种可能性:
- 您将在事件侦听器中编写所有使用返回值的函数调用。
- 您将遵循此 CLJS guide for Promises 并使用 JS Promises 或
clojure.core.async
。
经过大量阅读,我使用 回调 函数解决了这个问题:
(ns lopezsolerluis.fits)
(defn read-file [file callback]
(let [js-file-reader (js/FileReader.)]
(set! (.-onload js-file-reader)
(fn [evt]
(let [result (-> evt .-target .-result)
array (js/Uint8Array. result)]
(callback array))))
(.readAsArrayBuffer js-file-reader file)))
然后read-file
由此调用:
(ns lopezsolerluis.annie-web)
(defn procesar-archivo [result]
(js/console.log "Bloques: " result))
(defn input-file []
[:input {:type "file" :id "fits" :name "imagenFits" :accept "image/fits"
:on-change (fn [this]
(if (not (= "" (-> this .-target .-value)))
(let [^js/File file (-> this .-target .-files (aget 0))]
(fits/read-file file procesar-archivo)))
(set! (-> this .-target .-value) ""))}])
我添加了命名空间,因为令我惊讶的是回调机制甚至可以跨命名空间工作。好吧,也许这不应该让我感到惊讶;但我正在学习,对我来说是一个新概念。 :)
我回答我的问题以防它对其他人有用(这让我付出了很多代价!:))
我有一个使用 js/FileReader.
读取文件的函数:
(defn read-file [file]
(let [js-file-reader (js/FileReader.)]
(set! (.-onload js-file-reader)
(fn [evt]
(let [result (-> evt .-target .-result)
array (js/Uint8Array. result)]
{:content array}))) ; <- This is the value that 'read-file' should return
(.readAsArrayBuffer js-file-reader file)))
问题是我想return.-onload
方法的值FileReader
,但我只得到(当然)[=的值16=] 自然是 undefined
.
非常感谢!
编辑
在尝试 Martin Půda 的回答后,我认为问题与异步的事情有关。我测试了这段代码:
(defn read-file [file]
(let [js-file-reader (js/FileReader.)
reading-result (atom)
done? (atom false)]
(set! (.-onload js-file-reader)
(fn [evt]
(let [result (-> evt .-target .-result)
array (js/Uint8Array. result)]
(reset! reading-result {:content array})
(reset! done? true)
(js/console.log "in: " (:content @reading-result)))))
(.readAsArrayBuffer js-file-reader file)
;; (while (not @done?) (js/console.log (.-readyState js-file-reader)))
(js/console.log "out: " @reading-result)
@reading-result))
我得到 first out: undefined
的日志,然后 in:
的日志(与期望的结果)。
当我取消对行 (while...)
的注释时,我得到了 1
的无限循环...所以我认为该函数从未注意到 FileReader
已完成。 ..我不知道怎么解决这个问题...
试试这个:
(defn read-file [file]
(let [js-file-reader (js/FileReader.)
reading-result (atom)]
(set! (.-onload js-file-reader)
(fn [evt]
(let [result (-> evt .-target .-result)
array (js/Uint8Array. result)]
(reset! reading-result {:content array}))))
(.readAsArrayBuffer js-file-reader file)
@reading-result))
编辑: 参见 HTML5 FileReader how to return result?- 是的,它是异步的。我看到两种可能性:
- 您将在事件侦听器中编写所有使用返回值的函数调用。
- 您将遵循此 CLJS guide for Promises 并使用 JS Promises 或
clojure.core.async
。
经过大量阅读,我使用 回调 函数解决了这个问题:
(ns lopezsolerluis.fits)
(defn read-file [file callback]
(let [js-file-reader (js/FileReader.)]
(set! (.-onload js-file-reader)
(fn [evt]
(let [result (-> evt .-target .-result)
array (js/Uint8Array. result)]
(callback array))))
(.readAsArrayBuffer js-file-reader file)))
然后read-file
由此调用:
(ns lopezsolerluis.annie-web)
(defn procesar-archivo [result]
(js/console.log "Bloques: " result))
(defn input-file []
[:input {:type "file" :id "fits" :name "imagenFits" :accept "image/fits"
:on-change (fn [this]
(if (not (= "" (-> this .-target .-value)))
(let [^js/File file (-> this .-target .-files (aget 0))]
(fits/read-file file procesar-archivo)))
(set! (-> this .-target .-value) ""))}])
我添加了命名空间,因为令我惊讶的是回调机制甚至可以跨命名空间工作。好吧,也许这不应该让我感到惊讶;但我正在学习,对我来说是一个新概念。 :)
我回答我的问题以防它对其他人有用(这让我付出了很多代价!:))