Skip to content

Commit 4f22a31

Browse files
authored
Merge branch 'issue181' into async-chapter
2 parents 5c387fd + 665e898 commit 4f22a31

File tree

4 files changed

+77
-8
lines changed

4 files changed

+77
-8
lines changed

src/SUMMARY.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,7 @@
232232
- [Async](async.md)
233233
- [async/await](async/async-await.md)
234234
- [Async Blocks](async/async-blocks.md)
235-
- Futures
236-
- Executors
237-
- Polling
238-
- Pin
235+
- [Futures](async/futures.md)
239236
- [Async Channels](async/channels.md)
240237
- [Futures Control Flow](async/control-flow.md)
241238
- [Exercises](exercises/day-4/async.md)

src/async/async-await.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33
At a high level, async Rust code looks very much like "normal" sequential code:
44

5-
```rust,editable
5+
```rust,editable,compile_fail
66
use tokio::time;
77
8-
async fn count_to(i: i32) {
9-
for i in 1..10 {
8+
async fn count_to(count: i32) {
9+
for i in 1..=count {
1010
println!("Count in task: {i}!");
1111
time::sleep(time::Duration::from_millis(5)).await;
1212
}

src/async/async-blocks.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Similar to closures, a snippet of async code can be included inline in another
44
function with an async block:
55

6-
```rust, editable
6+
```rust,editable,compile_fail
77
use tokio::{time, task};
88
99
#[tokio::main]

src/async/futures.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Futures
2+
3+
What is the type of an async operation?
4+
5+
```rust,editable,compile_fail
6+
use tokio::time;
7+
8+
async fn count_to(count: i32) -> i32 {
9+
for i in 1..=count {
10+
println!("Count in task: {i}!");
11+
time::sleep(time::Duration::from_millis(5)).await;
12+
}
13+
count
14+
}
15+
16+
#[tokio::main]
17+
async fn main() {
18+
let _: () = count_to(13);
19+
}
20+
```
21+
22+
[Future](https://doc.rust-lang.org/nightly/src/core/future/future.rs.html#37)
23+
is a trait, implemented by objects that represent an operation that may not be
24+
complete yet. A future can be polled, and `poll` returns either
25+
`Poll::Ready(result)` or `Poll::Pending`.
26+
27+
```rust
28+
use std::pin::Pin;
29+
use std::task::Context;
30+
31+
pub trait Future {
32+
type Output;
33+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
34+
}
35+
36+
pub enum Poll<T> {
37+
Ready(T),
38+
Pending,
39+
}
40+
```
41+
42+
An async function returns an `impl Future`, and an async block evaluates to an
43+
`impl Future`. It's also possible (but uncommon) to implement `Future` for your
44+
own types. For example, the `JoinHandle` returned from `tokio::spawn` implements
45+
`Future` to allow joining to it.
46+
47+
The `.await` keyword, applied to a Future, causes the current async function or
48+
block to pause until that Future is ready, and then evaluates to its output.
49+
50+
An important difference from other languages is that a Future is inert: it does
51+
not do anything until it is polled.
52+
53+
<details>
54+
55+
* Run the example and look at the error message. `_: () = ..` is a common
56+
technique for getting the type of an expression. Try adding a `.await` in
57+
`main`.
58+
59+
* The `Future` and `Poll` types are conceptually quite simple, and implemented as
60+
such in `std::task`.
61+
62+
* We will not get to `Pin` and `Context`, as we will focus on writing async
63+
code, rather than building new async primitives. Briefly:
64+
65+
* `Context` allows a Future to schedule itself to be polled again when an
66+
event occurs.
67+
68+
* `Pin` ensures that the Future isn't moved in memory, so that pointers into
69+
that future remain valid. This is required to allow references to remain
70+
valid after an `.await`.
71+
72+
</details>

0 commit comments

Comments
 (0)