clojurescript чака обратно извикване

Имам функция, която връща резултата си чрез функция за обратно извикване. Почти като множество библиотеки с http-заявки.

Много пъти трябва да извикам тази функция няколко пъти, за да получа различни данни.

(get-data "key-a" (fn [res-a]
  (get-data "key-b" (fn [res-b]
    (get-data "key-c" (fn [res-c]
      (do-something res-a res-b res-c))))))) 

Опитвам се да създам функция, която прави горното да работи по следния начин:

(get-multi-data ["key-a" "key-b" "key-c"] 
                do-something)

Трябва да получа исканите данни във вектора и да предам резултатите на обратното извикване. Въпрос 1: Как може да изглежда функция като тази?

Въпрос 2: Възможно ли е чрез използване на core.async да се направи функция, която просто да връща данните? И да скрия напълно обратните повиквания?

(let [res (get-multi-data ["key-a" "key-b" "key-c"])]
  (do-something res))

person Drewes    schedule 01.03.2018    source източник
comment
Бих се опитал да използвам manifold за това. Има CLJS порт   -  person akond    schedule 01.03.2018


Отговори (1)


Можете да дефинирате функция, която връща get-muti-data функция за дадена get-data функция:

(defn multi-caller [data-getter] 
   (fn [xs callback]  
      (let [f (fn f [xs res] 
                (if (seq xs) 
                    (data-getter (first xs) #(f (rest xs) (conj res %)))
                    (apply callback res)))] 
           (f xs []))))

Това ще ви позволи да пишете

((multi-caller get-data) 
   ["key-a" "key-b" "key-c"] 
   do-something)

за да постигнете това, което искате.

Обърнете внимание, че извикванията get-data ще се извършват последователно, така че нямате полза от паралелизма.


Що се отнася до core.async, трябва да правите всички забавни неща в go-blocks. Не е възможно да се дефинира нормална функция на clojurescript, която изпълнява всички асинхронни неща и след това в крайна сметка връща резултат на извикващия.

person clojureman    schedule 29.03.2018