Deferred Execution and Dart's Concurrency Model
Tags: dart, async, concurrency
Published: 2017-12-07 17:07:18

---
title: Deferred Execution and Dart's Concurrency Model
published: true
description: In this article, we talk about what deferred execution is, and how Dart's Concurrency model makes it easy.
tags: #dart #async #concurrency
---

You gotta hand it to Google: they make languages with great asynchronousy models. Go (another Google language) is infamous for it's [simple concurrency](https://tour.golang.org/concurrency/1) model that makes it really easy to make your code asynchronous.

However, Go isn't the only Google language that wants to make your life in a concurrent world easier. Dart comes with it's own paradigms for making concurrency extremely easy.

## Keywords

[This](https://www.dartlang.org/guides/language/language-tour#asynchrony-support) is going to be a great reference for this article. If you haven't read this I would highly recommend it.

Asynchronous functions in Dart will have either `async` or `async*` in the signature of the function. This means that the function will return either a `Future` for `async`, or a `Stream` for `async*`. There are subtle differences between the two, but the premises are the same for both: you can _execute_ the function, and _continue_ execution without _waiting_ for the execution of the function to finish.

## `Future`

When writing code in Dart, you should use `Future` when  you want to are waiting for an object to come back, and ONLY one object to come back. That being said, it's still possible to return a `Future<List<int>>` from your API, but when it makes sense to, you might want to consider using a `Stream<int>` instead. I'll explain what the differences are in a second.

When you're consuming an API that returns a `Future`, there are a couple of different ways you can handle it:

```dart
import 'dart:async';

Future<Null> main() async {
  Future<String> name = futureName();
  print('Waiting for the name to come back...');
  name.then((theName) => print('Hello $theName!'));
}

Future<String> futureName() async {
  return new Future.delayed(new Duration(seconds: 3), () => 'Jake');
}
```

If you have ever used a promise in JavaScript, you might notice that a `Future` acts in a very similar way to a promise. There are a [variety](https://api.dartlang.org/stable/1.24.2/dart-async/Future-class.html) of different ways you can handle a `Future` depending on what your needs are.

This is an _okay_ way of handling the `Future` returned from `futureName()`, but I prefer using the `await` syntax:

```dart
import 'dart:async';

Future<Null> main() async {
  print('Waiting for the name to come back...');
  String name = await futureName();  
  print('Hello $name!');
}

Future<String> futureName() async {
  return new Future.delayed(new Duration(seconds: 3), () => 'Jake');
}
```

In this example, we're using the `await` keyword, which essentially tells Dart to wait for the `Future` to close and then return what the Future is supposed to return. The code is still asynchronous, but the code will wait before execution. Try moving the first print below the `await` and notice that it takes a few seconds before executing that statement.

With `Futures`s, it's possible to return `List`s as well:

```dart
import 'dart:async';

Future<Null> main() async {
  print('Just waiting for my list...');
  List<int> integers = await deferredExecution();
	for (var x in integers) {
    print(x);
  }
}

Future<List<int>> deferredExecution() async {
  List<int> list = [];
  int totalWait = 0;
	for (var x = 5; x >= 0; x--) {
    // sleep for x seconds...
    list.add(x);
    totalWait += x;
  }
  return new Future.delayed(new Duration(seconds: totalWait), () => list);
}
```

This isn't very elegant because we have to wait _so, so long_ in order for our integers to come back...

## Deferred Execution and `Stream`s

If you're returning a bunch of things that take a long time to come back, try returning a `Stream` and using deferred execution instead.

Deferred execution essentially means that you're returning back something that you can iterate over, but the items will come back asynchronously. If you have ever written C# code and you've used deferred execution before, Dart's `yield` keyword acts exactly the same as C#'s `yield`, but where C# [requires](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/yield) that methods that use `yield` return `Enumerable<T>`, Dart enforces that a `Stream` is returned.

So in the `deferredExecution()` function, we can change the code to use the `yield` keyword to return our integers more efficiently:

```dart
import 'dart:async';

Future<Null> main() async {
  Stream<int> integers = deferredExecution();
  print('Just waiting for my stream...');
  await for (var x in integers) {
    print(x);
  }
}

Stream<int> deferredExecution() async* {
  for (var x = 5; x >= 0; x--) {
    yield x;
    // sleep for x seconds...
    await new Future.delayed(new Duration(seconds: x));
  }
}
```

In this example, we're using an `await for` loop to iterate over the things that were retrieved from the `Stream`. This special syntax will return items back into the loop as they are retrieved until the `Stream` closes.

In this case, we still wait the same amount of time to get all of the information back, but this is more efficient because we are able to act on what's returned from the function as each element is returned thanks to deferred execution.

I hope that this made sense. I know that some of these examples weren't the best, but I hope that this was educational!