What is the difference between the Scala Future onComplete and andThen functions?


Answer: Both `andThen` and `onComplete` allow you to observe the result of some future via a callback function. However, `andThen` can be chained, and unlike `onComplete`, it guarantees the order in which callback functions will be applied. In addition, the callback given to `andThen` may be a partial function, handling only a subset of outcomes (e.g., only `Success` or only `Failure`).

Consider the following example using `andThen` and `map`:

```
def demoAndThen(fut: Future): Future = {
  fut.andThen { case Success(value) => println(s"andThen1: $value") }
    .andThen { case Success(value) => println(s"andThen2: $value") }
    .map { i =>
      println(s"map: $i")
      i
    }
}
```

When `fut` completes successfully, "andthen1: ...", "andThen2: ..." and "map: ..." will be printed in that order.

Consider the analogous example using `onComplete` and `map`:

```
def demoOnComplete(fut: Future): Future = {
  fut.onComplete { t: Try => println(s"onComplete1: $t") }
  fut.onComplete { t: Try => println(s"onComplete2: $t") }
  fut.map { i =>
    println(s"map: $i")
    i
  }
}
```

In this case, when `fut` completes successfully, "onComplete1: ...", "onComplete2: ..." and "map: ..." will be printed in some unspecified order.

Although `andThen` is chained, the callback function does not generally affect the outcome of the resulting `Future`. But be aware: if the callback throws some fatal errors, the resulting future will never complete.