Fork me on GitHub
David Pham16:01:04

Anyone worked with JavaScript promise in ClJS? Is there a good practice on how to bind the value of the promise? I used a global reagent-atom and reset! with the .then method, but is there a better way? I tried core.async channels as well, and was not successful. (I am working with D3.js)


wrote a small entry on the topic, along with a macro you might find useful:

David Pham17:01:10

thanks a lot!

David Pham18:01:57

How do you handle async get request in your code? Do you store the result in an atom? How do you make sure that the atom is not empty?


@neo2551 this depends a lot on what you're trying to do with the value in your application and the rest of your app's design


e.g. if you're building an application using reagent, then swapping or reseting an atom might make sense! since your app will re-render when the atom is changed. if you're using other libraries or designs, there might be other ways you'll want to do it

David Pham18:01:36

Ok! Then with reagent and re-frame it makes sense because it will trigger the components that should be updated? :)

David Pham18:01:54

I am sorry for the noob question, I am not extremely confident in async coding lol


typically, if you're using re-frame, you have an event that triggers the GET request right?


e.g. a user clicks a button, which dispatch's the [:load-user-details {:user-id 12345}] event or some such


at that point, you'd configure your :loader-user-details event-fx handler to do the GET request, and then when the data came back, it would dispatch another event with the data that would update your application's app-db


there's a good intro here for dealing with async in re-frame:

David Pham18:01:32

Thanks! I will look at it!

David Pham18:01:03

I think I could understand reframe because it was handling the trigger automatically. I was also curious in a lighter environment. Typically, just for reading data and plotting it. But you can’t really avoid side effects then.


Does anyone have any opinions on I use jsonschema a lot in my javascript application, and I'd like to add mrhyde as a way to ease interop with ajv and other js libraries. Is it more trouble than it's worth though? I can imagine a lot of things not working quite right and causing problems.


Hello, what is the fastest way to do this? : [1 2 3 4 5 8 9 10 14 15 16 18] -> [[1 5] [8 10] [14 16] [18]]?


I maintain a library that has a contiguous-by transducer. It’s not cljc at the moment but easy enough to copy


(miss/contiguous-by identity inc [1 2 3 4 5 8 9 10 14 15 16 18])


You know, there's an app for that


hmm, didn't work for those inputs. You could fiddle with it though and find interesting functions.


you'll probably need to describe some logic guiding your result.

Karol Wójcik20:01:48

Supposing that I want to use antd-design via cljsjs. Will the advanced compilation trim not used components or do I need to know some magic incantation? Btw does aliasing includes everything? What is preferred :refer or :as?


no, it will not trim unused components

Karol Wójcik20:01:32

How come? Why people contribute to cljsjs then?


it used to make it more convenient to use external JS


nowadays I would use shadow-cljs or the webpack strategy


From and ordered sequence of numbers I want to gather the intervals.


It doesnt even work as expected, but it's slow anyway, so are there any ideas how can I sort and group a collection if they are in one sequence, so [1 2 3], but not [1 2 4]?


assuming they're already in sorted order, I would use reduce but something kinda similar to what you're doing


on 1400 items it's 66ms, I use it for deciding if reservations are free or full, why is my approach slow? 😄


I try something with 'reduce', will check back 🙂


stateful transducer like partition-all might be a good choice


maybe something like this, but not written as fast:

(defn in-group?
  [prev curr]
  (= 1 (- curr prev)))

(let [r (reduce (fn [m v]
                 (if (or (empty? (:interval m))
                         (in-group? (last (:interval m)) v))
                   (update m :interval (fnil conj []) v)
                   (-> (update m :final (fnil conj []) (:interval m))
                       (dissoc m :interval))))
               (flatten  [(range 2) (range 4 8) (range 10 15)]))]
  (conj (:final r) (:interval r)))


@trailcapital Thank you, but unfortunately it is slower than my approach, I can't seem to find the fastest solution 😄


@paul931224 use recur rather than an actual recursive call in your example


@dpsutton how can I reach the previous element in partition-all? I need it for the comparison


@dpsutton okay, I try it 🙂


my idea was to mimic the source of partition-all, not use it. make a stateful transducer with an accumulating array


it is exactly the same speed with recur 😕


@paul931224 can you share what you're calling to benchmark it?


well, only (time (my-function the-range))


yeah, I just want to know what range you're passing in, so I can call the same one in my testing


oh, sorry, I misunderstood. well I make a reservation system where 12:30 is 12*60+30, so I count everything in minutes. I benchmark with a maximal 00:00-00:00 which is (range 1440), and random number of reservations., like [720 780]...


(concat (range 0 720) (range 780 900) (range 1000 1200)) for example, so no bigger vector than 1440 items


This seems to be a bit faster:

(defn split-interval
  ((fn f [prev remain]
       (empty? remain) [prev]
       (or (nil? prev)
           (= (first remain) (inc prev))) (f (first remain) (rest remain))
       :else [prev remain]))
   nil remainder))

(defn interval-getter []
  ((fn f [total remainder]
     (if (empty? remainder)
       (let [[interval rest] (split-interval remainder)]
         (f (conj total [(first remainder) interval]) rest))))
With 1500 items, executed 10,000 times repeatedly, mine takes 2s and yours takes 3s on my machine


mine is also getting the right end of the interval 🎆


I got large gains from moving away from recur and loop and using fn with non-tail recursion instead


@trailcapital I am kind of a beginner, how does the (()) double parentheses work? where do I give my range? 😕


(fn [] ...) defines a function, then to call the function you wrap it in parens, so... ((fn [x] (inc x)) 1) => 2


items is the range 🙂


@trailcapitalmy bad, Cursive messed up the copied code. It works perfectly and unimaginably fast. Thank you for your help, much appreciated.

👍 5