Clojurescript - 从匿名函数承诺回调中重复出现
Clojurescript - Recur from anonymous function promise callback
我正在使用 clojurescript 和 localforage 基于 promise 的存储库。我在本地存储中设置了如下结构作为键值对
"names" : ["name1","name2","name3"]
然后每个 "names" 是另一组值的键。
"name1": [val1,val2,val3]
我目前正处于拥有名称列表的位置,现在需要遍历该列表,获取每个值,然后 return 格式如下的地图:
{: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) 调用 return 是我无法以其他方式访问的承诺。
我的问题是,有没有一种方法可以将承诺值取出并重新出现在循环中,或者有更好的整体方法来做到这一点?
据我所知,无法选择您想 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
是否安全。
我正在使用 clojurescript 和 localforage 基于 promise 的存储库。我在本地存储中设置了如下结构作为键值对
"names" : ["name1","name2","name3"]
然后每个 "names" 是另一组值的键。
"name1": [val1,val2,val3]
我目前正处于拥有名称列表的位置,现在需要遍历该列表,获取每个值,然后 return 格式如下的地图:
{: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) 调用 return 是我无法以其他方式访问的承诺。
我的问题是,有没有一种方法可以将承诺值取出并重新出现在循环中,或者有更好的整体方法来做到这一点?
据我所知,无法选择您想 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
是否安全。