debounceOn<ChildEvent> method

System<State, Event> debounceOn<ChildEvent>({
  1. ChildEvent? test(
    1. Event event
    )?,
  2. required Duration duration,
})

Drop conditional events when they are dispatched in high frequency.

It's similar to Rx.observable.debounce

Usage Example

searchSystem
  ...
  .on<UpdateKeyword>(
    reduce: (state, event) => state.copyWith(keyword: event.keyword)
  )
  .debounceOn<UpdateKeyword>(
    duration: const Duration(seconds: 1)
  )
  ...

Above code shown if UpdateKeyword event is dispatched with high frequency (quick typing), system will drop these events to reduce unnecessary dispatching, it will pass (not drop) event if 1 second has passed without dispatch another UpdateKeyword event.

API Overview

This operator will drop candidate event if condition is met and these events are dispatched with high frequency.

system
  .debounceOn<ChildEvent>(
    test: (event) { // -> test if we are concern about this event, this parameter is optional,
                    // if `test` is omitted, then we will try safe cast `Event event` to `ChildEvent? event`.
      // `Event event` here is candidate event
      // return `ChildEvent childEvent` if we are concern about it
      // return null if we are not concern about it
      ...
    },
    duration: ... // time interval used for judgment
  )
  ...

Implementation

System<State, Event> debounceOn<ChildEvent>({
  ChildEvent? Function(Event event)? test,
  required Duration duration,
}) {
  final localTest = test ?? safeAs;
  return eventInterceptor<_DebounceOnContext>(
    createContext: () => _DebounceOnContext(),
    interceptor: (context, dispatch, event) {
      final childEvent = localTest(event);
      if (childEvent == null) {
        dispatch(event);
      } else {
        final identifier = Object();
        context.identifier = identifier;
        Future<void>.delayed(duration).then((_) {
          if (identical(context.identifier, identifier)) {
            dispatch(event);
          }
        });
      }
    },
    dispose: (context) {
      context.identifier = null;
    },
  );
}