Skip to content

restartable() executes all queued events after async delay instead of keeping only the latest one #4718

@MohammadBahlaq

Description

@MohammadBahlaq

Description

Hi 👋

I’m experiencing an unexpected behavior when using restartable() with flutter_bloc and bloc_concurrency.

I have a single event handler that processes multiple events and includes a long async operation (Future.delayed).
The expectation is that only the latest event should be executed, but instead all previous events are executed sequentially after the delay.

Code example:

class SearchBloc extends Bloc<SearchEvent, SearchState> {
SearchBloc() : super(SearchInitial()) {
on(_blocActions, transformer: restartable());
}

Future _blocActions(
SearchEvent event,
Emitter emit,
) async {
if (event is Search) {
await _search(event, emit);
}
}

Future _search(Search event, Emitter emit) async {
emit(SearchLoading());

// Simulating an expensive async operation
await Future.delayed(const Duration(seconds: 5));

log(event.searchText);

emit(SearchSucces(
  stringResults: event.searchText,
  results: const [],
));

}
}

Steps to reproduce

Dispatch Search("a")

Dispatch Search("ab")

Dispatch Search("abc") quickly (within 5 seconds)

Expected behavior

Only the latest event should complete:

abc

All previous Search events should be canceled by restartable().

Actual behavior

After 5 seconds, all events are executed:

a
ab
abc

This gives the impression that events are being queued and executed after the async operation finishes, instead of being properly canceled.

Question

Is this behavior expected when using restartable() with a single handler?

Is restartable() only meant to cancel previous events after they start, but not prevent already awaited operations from completing? If yes How cloud I call api's for search? It will call the search api every character written.

Is there a recommended pattern to ensure that only the latest event result is emitted, similar to switchMap behavior?

Environment

flutter_bloc:

bloc_concurrency:

Flutter:

Thanks for your help 🙏
This behavior is a bit confusing and hard to reason about in real-world search use cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds triageThis issue requires triagequestionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions