You complete me, unless you already have a Dart future

Dart Protip: if you already have an instance of Future, you probably don't need a Completer. Simply return the last Future.



If you find yourself using Completers inside of Futures, like this:


  // NOT recommended.

  Future doStuff() {
    Future future = someAsyncProcess();
    Completer completer = new Completer();

    future.then((msg) {
      bool result = msg.result as bool;

      completer.complete(result);
    });

    return completer.future;
  }


then I'm happy to report there's a better way. Dart's Futures chain, so you can do this instead:


  // Recommend.
  Future doStuff() {
    return someAsyncProcess().then((msg) => msg.result);
  }


The last Future in a chain can return another Future, or simply a value. It's always a good idea to return a Future from a function that uses a Future. This way, the caller knows when the method finished its async work, and can properly handle potential errors.

Completers are great for bridging a callback-based API with a Future-based API. For example, suppose your database driver doesn't use Futures, but you need to return a Future. Try this code:

  // A good use of a Completer.

  Future doStuff() {
    Completer completer = new Completer();
    runDatabaseQuery(sql, (results) {
      completer.complete(results);
    });
    return completer.future;
  }

To learn more about Futures, read Using Future Based APIs. To step up your game, read Futures and Error Handling.

Enjoy!
Post a Comment

Popular posts from this blog