Clojurescript - возврат из анонимного вызова функции - PullRequest
0 голосов
/ 04 декабря 2018

Я работаю с clojurescript и localforage библиотекой хранения на основе обещаний.У меня есть структура, подобная следующей в localstorage, как пары значений ключа

"names" : ["name1","name2","name3"]

Где тогда каждое «имя» является ключом для другого набора значений.

"name1": [val1,val2,val3]

I 'Сейчас я нахожусь в точке, где у меня есть список имен, и теперь мне нужно перебрать этот список, получить значения для каждого из них, а затем вернуть карту в следующем формате:

{: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) возвращает обещание, к которому я не могу получить доступ в противном случае.

Тогда у меня вопрос, есть ли способ получить значение этого обещания и вернуться к циклу, или лучший способ сделать это в целом?

1 Ответ

0 голосов
/ 04 декабря 2018

Я не знаю, как выбрать то, что вы хотите 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.

...