Bloc: Can I run events in parallel in the same bloc instance?

Created on 31 Oct 2019  路  2Comments  路  Source: felangel/bloc

I have events that do long synchronisations in the background and they have to update loading status, but at the same time I have to fire other events, unfortunately the bloc's event channel gets blocked, preventing me from firing other events. Can I solve this problem without creating another bloc instance?

Here's my code:

  @override
  Stream<MailState> mapEventToState(
    MailEvent event,
  ) async* {
    if (event is FetchFolders) yield* _fetchFolders(event);
    if (event is RefreshFolders) yield* _refreshFolders(event);
    if (event is SelectFolder) yield* _selectFolder(event);
    if (event is CheckFoldersUpdateByTimer) yield* _checkFoldersUpdateByTimer(event);
    if (event is RefreshMessages) yield* _refreshMessages(event);
  }
  Stream<MailState> _fetchFolders(FetchFolders event) async* {
    yield FoldersLoading();

    try {
      final List<Folder> folders = await _methods.getFolders();

      if (folders.isNotEmpty) {
        _selectedFolder = folders[0];
        yield FoldersLoaded(folders, _selectedFolder);
        yield SubscribedToMessages(
            _methods.subscribeToMessages(_selectedFolder));
        final List<Folder> foldersWithInfo = await _methods.updateFoldersHash(
          _selectedFolder,
        );

        yield FoldersLoaded(foldersWithInfo, _selectedFolder);

        yield MessagesSyncing();

        // very long running process, up to 40 sec
        await _methods.syncFolders(
            localId: _selectedFolder.localId, syncSystemFolders: true);

        yield MessagesSynced();
      } else {
        yield FoldersEmpty();
      }
    } catch (err) {
      yield MailError(err.toString());
    }
  }



md5-b86f2b251316869cdcb71bac7bc3dbe7



  Stream<MailState> _selectFolder(SelectFolder event) async* {
    try {
      final List<Folder> folders = await _methods.getFolders();
      _selectedFolder = event.folder;
      yield FoldersLoaded(folders, _selectedFolder);
      yield SubscribedToMessages(_methods.subscribeToMessages(_selectedFolder));
    } catch (err) {
      yield MailError(err.toString());
    }
  }
question

Most helpful comment

@felangel That works perfectly! Thank you for the lightning fast response, the awesome library and for help. You're a great person!

All 2 comments

Hi @VadimOsovsky 馃憢
Thanks for opening an issue!

In your case, I would recommend having events to initiate the long-running processes and then add new events when the processes have completed. This will allow your bloc to process multiple long-running requests in the background and handle their results independently without blocking the event loop.

_methods.syncFolders(
  localId: _selectedFolder.localId, syncSystemFolders: true
).then((results) => add(MessagesSynced(results)));

Let me know if that helps 馃憤

@felangel That works perfectly! Thank you for the lightning fast response, the awesome library and for help. You're a great person!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

craiglabenz picture craiglabenz  路  3Comments

clicksocial picture clicksocial  路  3Comments

wheel1992 picture wheel1992  路  3Comments

ricktotec picture ricktotec  路  3Comments

1AlexFix1 picture 1AlexFix1  路  3Comments