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!

Popular posts from this blog

Converting Array to List in Scala

I ported a JavaScript app to Dart. Here's what I learned.

Null-aware operators in Dart