felangel / bloc

A predictable state management library that helps implement the BLoC design pattern
https://bloclibrary.dev
MIT License
11.53k stars 3.37k forks source link

fix: How to listen to multiple streams in a single event? #4191

Closed onism0106 closed 3 weeks ago

onism0106 commented 3 weeks ago

I need listen to the play state and play progress of a music player. These belong to two different streams. When I use await on the first emit.forEach(), the second emit.forEach does not work.


FutureOr<void> _onStarted(
    PlayerStarted event,
    Emitter<MusicPlayerState> emit,
  ) async {
    Duration? duration = await _audioPlayer.setFilePath(musicModel.filePath);
    emit(state.copyWith(musicDuration: duration));
    await emit.forEach(_audioPlayer.playerStateStream, onData: (event) {
      return state.copyWith(playerState: event);
    });
    await emit.forEach(
      _audioPlayer.positionStream,
      onData: (duration) {
        logger.i("duration:$duration");
        return state.copyWith(
            playingProgressInMilliSeconds: duration?.inMilliseconds ?? 0);
      },
    );
  }
felangel commented 3 weeks ago

Hi @onism0106 👋 Thanks for opening an issue!

emit.forEach will only complete when the provided stream is closed. In this case, it sounds like the _audioPlayer.playerStateStream is not closed so you'll probably want to combine the two streams into one and then use emit.ForEach on the combined stream. You can use something like combineLatest2 from package:rxdart or write your own.

Hope that helps!