flutterdart 中的Completer

24 min read
/// Loads and parses the [SharedPreferences] for this app from disk.
  ///
  /// Because this is reading from disk, it shouldn't be awaited in
  /// performance-sensitive blocks.
  static Future<SharedPreferences> getInstance() async {
    if (_completer == null) {
      final Completer<SharedPreferences> completer =
          Completer<SharedPreferences>();
      try {
        final Map<String, Object> preferencesMap =
            await _getSharedPreferencesMap();
        completer.complete(SharedPreferences._(preferencesMap));
      } on Exception catch (e) {
        // If there's an error, explicitly return the future with an error.
        // then set the completer to null so we can retry.
        completer.completeError(e);
        final Future<SharedPreferences> sharedPrefsFuture = completer.future;
        _completer = null;
        return sharedPrefsFuture;
      }
      _completer = completer;
    }
    return _completer!.future;
  }

Completer允许你做某个异步事情的时候,调用c.complete(value)方法来传入最后要返回的值。最后通过c.future的返回值来得到结果,(注意:宣告完成的complete和completeError方法只能调用一次,不然会报错), 相当于 Promise.resolvet和reject, 支持传入泛形

 test() async {
    Completer c = new Completer();
    for (var i = 0; i < 1000; i++) {
      if (i == 900 && c.isCompleted == false) {
        c.completeError('error in $i');
      }
      if (i == 800 && c.isCompleted == false) {
        c.complete('complete in $i');
      }
    }

    try {
      String res = await c.future;
      print(res); //得到complete传入的返回值 'complete in 800'
    } catch (e) {
      print(e);//捕获completeError返回的错误
    }
  }