初始化我的 BLoC 时应该如何处理异步调用?

How should I handle asynchronous calls when initializing my BLoC?

我正在使用 Provider 包向我的 Flutter 应用程序提供 BLoC 对象(手写,不使用 blocflutter_bloc 包)。我需要进行一些异步调用才能正确初始化 BLoC(例如,来自 SharedPreferences 的设置和其他保存的信息)。到目前为止,我已经将那些 async 调用编写到几个单独的函数中,这些函数在我的 BLoC 的构造函数中调用:

class MyBloc {

  MySettings _settings;
  List<MyOtherStuff> _otherStuff;

  MyBloc() {
      _loadSettings();
      _loadOtherStuff();
  }

  Future<void> _loadSettings() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    // loads settings into _settings...
  }

  Future<void> _loadOtherStuff() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    // loads other stuff into _otherStuff...
  }
}

我想保证 _loadSettings()_loadOtherStuff() 在我们深入应用程序之前完成,以便依赖 settings/other 的代码加载正确的信息(对于例如,我希望在外出进行一些网络呼叫、初始化通知等之前加载设置。

据我了解,构造函数不能是异步的,所以我不能在构造函数上 await。我试过给我的 BLoC 一个 init() 函数(或类似的东西)调用 _loadSettings() and/or _loadOtherStuff(),但我很难找到一个好地方把它。

我应该把这些电话放在哪里?还是我误会了async/await?

您可以使用流来侦听完成。

class MyBloc {

  MySettings _settings;
  List<MyOtherStuff> _otherStuff;

  final _completer = StreamController<Void>.broadcast();

  Stream<void> get completer => _completer.stream;


  MyBloc() {
    allInit();

  }

  allInit()async{
    await _loadSettings();
    await _loadOtherStuff();
    _completer.sink.add(null);
  }

  Future<void> _loadSettings() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();


    // loads settings into _settings...
    return;
  }

  Future<void> _loadOtherStuff() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    // loads other stuff into _otherStuff...
    return;
  }


}

然后你使用一个streamBuilder

  return StreamBuilder(
    stream: myBloc.completer,
    builder: (context, AsyncSnapshot snapshot) {
      if (!snapshot.hasData) return Text('loading...');
    //stuff to run after init
  }, 

我最后还使用了 Future.wait() 的一些帮助:

Future.wait([_loadSettings(), _loadOtherStuff()]).then((_) => _doMoreStuff());

这确保在我们继续之前完成前两个。