The core definition

In Rust, a future is an asynchronous computation that can be driven to produce a value. It represents a value that may become available in the future, but which requires pushing along the computation to produce it.

We’ve already seen the core definitions of the Future trait, describing such computations:

  1. /// An asynchronous computation that completes with a value or an error.
  2. trait Future {
  3. type Item;
  4. type Error;
  5. /// Attempt to complete the future, yielding `Ok(Async::WillWake)`
  6. /// if the future is blocked waiting for some other event to occur.
  7. fn get(&mut self) -> AsyncResult<Self::Item, Self::Error>;
  8. // ... and a large number of default methods that we'll meet shortly!
  9. }
  10. type AsyncResult<T, E> = Result<Async<T>, E>;
  11. enum Async<T> {
  12. /// Work completed with a result of type `T`.
  13. Done(T),
  14. /// Work was blocked, and the task is set to be woken when ready
  15. /// to continue.
  16. WillWake,
  17. }

Just calling get once does not guarantee that a final value will be produced, and if the future is blocked waiting on some other event to occur, it is not guaranteed to make progress until get is called again. The first part of this chapter will focus on exactly who calls get, and when.

What makes futures interesting is that, by abstracting out the very general idea of “computing something asychronously”, we make it possible to combine such computations in expressive and surprising ways. This also informs their relationship to tasks: a task is generally made up of a number of smaller futures that have been stitched together.