我正在使用clojurescript和localforage基于Promise的存储库。我在localstorage中设置了以下结构作为键值对
"names" : ["name1","name2","name3"]
那么每个“名称”都是另一组值的键。
"name1": [val1,val2,val3]
我目前在这里有名称列表,现在需要遍历该列表,获取每个列表的值,然后返回格式如下的地图:
{:name1 [val1,val2,val3] :name2 [val1,val2]}
为此,我提出了以下代码段:
(defn get-project-dates [project-map]
"Handles getting all the times/dates for project"
(loop [i 0
project-dates {}]
(if (= i (count project-map))
project-dates
(.then (.getItem localforage (nth project-map i)) (fn [promiseVal]
(recur (inc i) (conj project-dates {(key (nth project-map i)) promiseVale})))))))
不幸的是,这不起作用,因为它没有返回到循环,而是返回到(fn)。但是,此(fn)回调是必需的,因为(.getItem)调用会返回一个我无法访问的承诺。
然后我的问题是,有没有办法使承诺值消失并重新循环,或者有更好的总体方法呢?
答案 0 :(得分:1)
我不知道如何选择recur
。据我所知,它完全取决于范围。
您可以使它成为直接的递归函数。您可以通过几种方法进行设置:
; Give it two argument lists. The 1-arity version is meant to be called by the user,
; while the 3-arity version is meant for recursive calls
(defn get-project-dates
([project-map i project-dates]
(if (= i (count project-map))
project-dates
(.then (.getItem localforage (nth project-map i))
(fn [promiseVal]
(get-project-dates
project-map
(inc i)
(conj project-dates {(key (nth project-map i)) promiseVale}))))))
([project-map]
(get-project-dates project-map 0 {})))
或
(defn get-project-dates [project-map]
; Define a local recursive function called "rec" (or whatever)
(letfn [(rec [i project-dates]
(if (= i (count project-map))
project-dates
(.then (.getItem localforage (nth project-map i))
(fn [promiseVal]
(rec
(inc i)
(conj project-dates {(key (nth project-map i)) promiseVale}))))))]
; Then start the recursion off
(rec 0 {})))
第二个优点是不需要不断传递project-map
以及更简洁的函数名。
当然,如果您可能有过多的递归调用,则需要谨慎。您需要测试以查看缺少recur
是否安全。