ClojureScript - Assoc не работает внутри обещания - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть множество произведений искусства.Я хочу найти длину маршрута и связать ее с каждым произведением искусства.

Мой код будет выглядеть следующим образом:

(defn load-art-routes [art-list ctx]
 (doall (map-indexed (fn [index art]
   (let [user-location (select-keys (:coords (sub> ctx :geolocation)) [:latitude :longitude])
         art-location (:geoLocation art)]
       (->> (map-request {:origin (str (:latitude user-location) "," (:longitude user-location))
                     :destination (str (:lat art-location) "," (:lon art-location))
                     :mode (name (sub> ctx :transition-mode))})
             (p/map (fn [data]
                   (let [route-length (ocall js/Math "round" (/ (get-in data [:routes 0 :legs 0 :distance :value]) (* 0.621371192 1000)) 2)
                         route-duration (ocall js/Math "floor" (/ (get-in data [:routes 0 :legs 0 :duration :value]) 60))]
                     (js/console.log "load-art-routes route-length " route-length")
                     (assoc art :route-length route-length))))
             (p/error (fn [error]
                       (util/log (str "GOOGLE DIRECTIONS API ERRORS" params) error)
                       ))))) art-list))
                       art-list)
(defn map-request [params]
 (when params
   (let [endpoint google-directions-api-endpoint]
     (->> (make-get-req (str endpoint "&" (encode-query-params params))
                        {})
          (p/map (fn [data]
                   (util/log "GOOGLE DIRECTIONS API " data)
                   data))
          (p/error (fn [error]
                     (util/log (str "GOOGLE DIRECTIONS API ERRORS" params ) error)
                     ))))))

Расчет длины маршрута выполнен правильно, но Assoc не работает.На самом деле это не ассоциируется.Я не знаю, в чем проблема.Кто-нибудь может мне помочь?

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Похоже, что вы пытаетесь написать "изменяемый" код.

Переформатирование кода и исправление одной ошибки делает это более очевидным:

(defn load-art-routes [art-list ctx]
  (doall (map-indexed (fn [index art]
                        (let [user-location (select-keys (:coords (sub> ctx :geolocation)) [:latitude :longitude])
                              art-location (:geoLocation art)]
                          (->> (map-request {:origin (str (:latitude user-location) "," (:longitude user-location))
                                             :destination (str (:lat art-location) "," (:lon art-location))
                                             :mode (name (sub> ctx :transition-mode))})
                               (p/map (fn [data]
                                        (let [route-length (ocall js/Math "round" (/ (get-in data [:routes 0 :legs 0 :distance :value]) (* 0.621371192 1000)) 2)
                                              route-duration (ocall js/Math "floor" (/ (get-in data [:routes 0 :legs 0 :duration :value]) 60))]
                                          (js/console.log "load-art-routes route-length " route-length)
                                          (assoc art :route-length route-length))))
                               (p/error (fn [error]
                                          (util/log (str " GOOGLE DIRECTIONS API ERRORS " params) error)
                                          ))))) art-list))
  art-list)

load-art-routes просто возвращает оригиналart-list и пинки какой-то работы в обещаниях.Эти обещания только обновляют свои версии списка, но, учитывая, что мы используем неизменяемые структуры данных, возвращаемые art-list сами остаются неизменными.Есть также подозрительная секунда art-list в вызове p/error?

Возможно, вы захотите реструктурировать это так, чтобы оно возвращало Promise или принимало обратный вызов, который будет вызван один раз для всех route-lengthбыли вычислены.

0 голосов
/ 22 февраля 2019

Пожалуйста, упростите этот пример!В процессе вы обнаружите проблему.

Сначала обновите свой вопрос, включив в него require, который показывает, что такое p/map, p/error и т. Д.Кроме того, поместите map-request перед load-art-routes, как это должно быть в вашем исходном файле.

Затем вы должны начать с удаления оператора ->> последнего потока и использовать let с именами для промежуточногозначения:

(let [aa (map-request ...)
      bb (p/map (fn [data] ...)   aa)
      cc (p/error (fn [error] ...) bb) ]
  <bb or cc here?> )

Я подозреваю, что ваш p/error вызов глотает результаты p/map и возвращает nil.

...