Fork me on GitHub

In case someone knows how to help 🙂


you are creating a new debounce channel every time you loop in your go loop, you need to create one debounce channel and use the same one for every iteration of your loop


Oh, it makes sense, let me test


Alright, that fixes the issue 😄 but introduce another


If I call multiple times the put!, it does not print the last one only


because the out channel is the same


For example, if I call put! 8 times, it prints 8 times with a delay of 1000ms, I was expecting to print only one time, the last one after the 1000ms


@UKFSJSM38 what are the expected semantics? 1. react to first value as soon as possible 2. debounce for timeout (drop all but the last value seen during this time) 3. return the last value (if seen) after timeout 4. repeat (1) ^ Or something else?


the function as written will only consume from the input once a second, and everything it consumes from the input goes to the output


I expect to always debounce, even if the first, second or any time


my description isn't right


• If I call the N time and wait for the ms, it'll print after the ms. • If I call M times inside the ms window, it will print only the last one • every new input, should reset the ms (I expect that from every debounce logic)


Is that clear/makes sense?


if a new input comes in within 1 second of the previous input it should drop the previous


and a new input will cause it to reset the 1 second timer

☝️ 3

The way I understand it, debounce does not usually reset ms after every input; debounce usually guarantees the first input is returned as fast as possible and then at most one input is returned after timeout passes (which input is returned is usually specific to the domain)


so with your example code changed so the go-loop is like

(let [c (debounce in 1000)]
  (async/go-loop []
    (println (async/<! c))
I think it behaves like what you described


if I write a bunch of values all at once, only one is printed, if I write three values with a 500 ms delay between them, only one is printed, if I write three with a 1000 ms delay between them, then all three are printed


Oh, that makes sense! and it's quite simple :man-facepalming: thank you very much @U0NCTKEV8!


I confirmed it works as I expected


Possibly not too helpful, but here’s what I wrote when I needed something similar a few weeks ago. Shuts down fine when the input channel closes. (defn throttle "Speed limit messages coming into in-ch, echoing to out-chan after a timeout." [in-ch out-ch] (go-loop [held-value nil] (if held-value (alt! in-ch ([v] (when v (recur v))) (a/timeout 500) (do (>! out-ch held-value) (recur nil))) (when-let [v (<! in-ch)] (recur v)))))


Yeah, I tried something like that, but it's a throttle indeed, I want somethig that accepts multiple inputs but delay to take a action


anyway, thanks for the input


Unless I completely misunderstand the debounce function, I think I’m doing the same thing: as values come in I recur with the most recent value, discarding earlier values, until a timeout, at which point I flush the last value seen. In fact, the only significant difference seems to be that debounce does a condp to determine the channel, whereas I do an alt! and don’t need that. (Also, the version you posted doesn’t seem protected against input closing; the later one on GitHub looks fine.) So, perhaps I don’t understand what you’re trying to achieve?


Yes, thanks for the help, I fixed it here: Also I explains exactly what I meant, sorry for not being clear