-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add debouncing functionality #14
Comments
I've been thinking about a different solution to this by the way. Option 1 If different fetchers had unique IDs, dispatched actions from a fetcher could go into some internal state such as:
When a fetch starts, add it to the set and perform the effect. If another fetch gets triggered while this one is in progress (already in set), (discard it / debounce). When the effect completes, remove the id from the set. It's basically a lock during a fetch. Option 2 Another possibility I've been thinking about, might be something like storing the AsyncActions that have triggered Effects until the future completes. Something like that is probably simpler, and similar I guess to the debouncing implementation in a way. Some method to dispatch the Effect would also store the action temporarily (in model or somewhere else?). The difference is that this would happen in the Option 2.5 Similar to option 2 but I realise that maybe you can use an Something like the above should be better than debouncing because what is a good interval to debounce an action within? I've found it's a bit latency dependent. If your pots take longer than the debounce interval to resolve then the fetch action can get re-triggered while your model is still reaching a 'steady state'. I realise this may be out of scope for Diode, just throwing it out there, and I expect there is more to it for a complete solution. I think I'll eventually play with something like this though. Edit: I actually still hit cases where the debounce interval isn't high enough, which results in a cascading flood of requests, which in turn pushes the resolution time up to the point where "it's not going to finish in a reasonable amount of time". I definitely don't trust debouncing as a strategy to solve this problem enough so will probably at the very least implement something like the above. |
Hi ! I can't access to the gist but I need also debouncing (but not the same case I think) to parse input in Javascript but it's too costly to parse input for each key. My naive code below : case class CancelDebounce(handle: SetTimeoutHandle, ifCanceled: () => Unit) {
def apply() {
ifCanceled()
clearTimeout(handle)
}
}
case class DebouncedException() extends Exception("Debounced")
class DebounceJS extends RunAfter {
// OK only in JS
private var activeTimeout: Option[CancelDebounce] = None
override def runAfter[A](delay: FiniteDuration)(f: => A) = {
val p = Promise[A]()
val oldTimeout = activeTimeout
activeTimeout = None
oldTimeout.foreach(_())
activeTimeout = Some(CancelDebounce(
setTimeout(delay)({
activeTimeout = None
p.success(f)
}),
() => () /*p.failure(DebouncedException())*/ ))
// With p.failure, the error will be received by handleError(msg: String)
// so we can't catch this error properly
// Need to change handleError(msg:String) to a handleError(action:Action, error: Throwable)
// Without p.failure, the promise will never be completed
// Maybe a problem with any long-time application
// Can cause memory leaks with lot of debouncing usage ??
p.future
}
} Now I can use it with : // I use object because DebounceJS must be persistent as a singleton
object DebounceInput extends DebounceJS
// Instead of the implicit runAfterJS, I use my DebounceJS instance
Effect.action(ActionToDispatch()).after(300.millis)(DebounceInput) |
Quick and dirty rushed implementation. Could be useful for some ideas.
EDIT: Original gist deleted but I dug up an old commit which should work.
The text was updated successfully, but these errors were encountered: