-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
feat: create debounce and debounce first transformers #4268
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #4268 +/- ##
===========================================
- Coverage 100.00% 99.52% -0.48%
===========================================
Files 31 33 +2
Lines 803 839 +36
===========================================
+ Hits 803 835 +32
- Misses 0 4 +4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
|
||
/// {@macro debounce} | ||
EventTransformer<E> debounce<E>([ | ||
Duration duration = const Duration(milliseconds: 300), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be nice to have the duration be a required, named argument and to align with the API from package:stream_transform. In fact, we already depend on package:stream_transform so I think we should be able to dramatically simplify the implementation here.
I'm thinking the method signature could look something like:
EventTransformer<E> debounce<E>({
required Duration duration,
bool leading = false,
bool trailing = true,
}) {...}
This would also allow us to remove debounceFirst
altogether and there'd just be a single debounce
transformer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also just remembering why I never included debounce
to begin with -- because it's purely rate limiting the event stream but doesn't indicate how the emitted events are processed (e.g. are they still processed concurrently, sequentially, etc?).
In other words, let's say you apply a debounce(10ms)
and we have something like:
Event 1 -- 10ms -- Event 2 -- 10ms -- Event 3
And let's say Event 1 takes 30ms to process so by the time Event 2
is added, Event 1
still hasn't finished processing what should the behavior be? This is why I feel debounce
doesn't quite fit here unless it also accepts a converter function that allows the user to define how the debounced events should be processed.
Left a comment based on my recollection and I think it'd be helpful to better understand the problem we're solving here. Can you maybe describe some real-world use-cases that would benefit from a It's also worth nothing that you can already trivially apply a debounce with any of the existing transformers like: import 'package:bloc/bloc.dart';
import 'package:bloc_concurrency/bloc_concurrency.dart';
import 'package:stream_transform/stream_transform.dart';
/// Debounce events and the process the emitted events concurrently.
EventTransformer<E> concurrentDebounce<E>({
required Duration duration,
bool leading = false,
bool trailing = true,
}) {
return (events, mapper) {
return concurrent<E>().call(
events.debounce(duration, leading: leading, trailing: trailing),
mapper,
);
};
}
/// Debounce events and the process the emitted events sequentially.
EventTransformer<E> sequentialDebounce<E>({
required Duration duration,
bool leading = false,
bool trailing = true,
}) {
return (events, mapper) {
return sequential<E>().call(
events.debounce(duration, leading: leading, trailing: trailing),
mapper,
);
};
} Hopefully that gives you a better sense of why a |
Thank you for the feedback! The main real-world use-case for a I see your point that Thanks for suggesting the changes to the method signature, like making |
…ing are both false
Just pushed my changes, wanted to note on a few things:
|
Thanks for all the hard work. The problem I'm having is, as I mentioned, An event transformer = an optional event filter + a required event mapper. Debounce is just an event filter (it doesn't imply anything about how the debounced events will be processed). In addition, it's trivial for folks to create their own custom debouncing transformer: import 'package:bloc/bloc.dart';
import 'package:bloc_concurrency/bloc_concurrency.dart';
import 'package:stream_transform/stream_transform.dart';
EventTransformer<E> concurrentDebounce<E>({
required Duration duration,
bool leading = false,
bool trailing = true,
}) {
return (events, mapper) {
return concurrent<E>().call(
events.debounce(duration, leading: leading, trailing: trailing),
mapper,
);
};
}
EventTransformer<E> sequentialDebounce<E>({
required Duration duration,
bool leading = false,
bool trailing = true,
}) {
return (events, mapper) {
return sequential<E>().call(
events.debounce(duration, leading: leading, trailing: trailing),
mapper,
);
};
} It seems like the bigger issue here is the lack of advanced docs on writing event transformers which I am happy to work on. For now though, I don't think it makes sense for a Hope that makes sense and sorry for leading you down this rabbit hole -- I totally forgot why I didn't do this in the first place! Closing for now but happy to continue the discussion 👍 |
Status
READY
Breaking Changes
NO
Description
This PR introduces a new transformer:
Debounce
This is the traditional debounce transformer. When any event is received, a "quiet period" will be created, based on the
duration
provided. When the window completes, the last event received will be processed.Leading
When
leading = true
, then the first event will not be debounced, rather processed. The "quiet period" will still be created and the last received event will still be processed.Transformer
After the "quiet period" is complete, it's possible that the previous event hasn't resolved yet, necessitating a second transformer to handle the events to process. The
concurrent
transformer is the default here.Type of Change