Search code examples
dartdart-async

Questions about using Futures and Completers


Hey have I read all I can find about futures, but I would like some more advice on proper usage.

I am writing an API library, that bridges the gap between HTTP Requests and the app. So I use the future returned by HTTP in most cases, however sometimes the data is already retrieved. Is that the appropriate time to use a Completer?

ex.

String _someData = "";

Future<String> getSomeData(){
  if (_someData == ""){
    return Api.getSomeData().then((String someData){
      _someData = someData;
      return _someData;
    });
  } else {
    var completer = new Completer();
    completer.complete(_someData);
    return completer.future;
  }
}

-edit- Also if I create a Completer, but end up not using its future or calling complete. Will that cause a mem leak? Should I call its complete method or dispose of it somehow?

Thanks :)


Solution

  • Use an async function instead.

    import "dart:async";
    
    String _someData = "";
    
    Future<String> getSomeData() async {
      if (_someData == "") {
        _someData = await Api.getSomeData();
      }
    
      return _someData;
    }
    

    Compiler generates approximately the following code:

    import "dart:async";
    
    String _someData = "";
    
    Future<String> getSomeData() {
      var $_awaiter = new Completer<String>();
      try {
        if (_someData == "") {
          Api.getSomeData().then(($) {
            $_awaiter.complete($);
          }).catchError((e, s) {
            $_awaiter.completeError(e, s);
          });
    
          return $_awaiter.future;
        } else {
          $_awaiter.complete(_someData);
          return $_awaiter.future;
        }
      } catch (e, s) {
        $_awaiter.completeError(e, s);
        return $_awaiter.future;
      }
    }