I'm not sure if tokio
is similar to the event loop in Javascript, also a non-blocking runtime, or if it can be used to work in a similar way. In my understanding, tokio
is an runtime for futures in Rust. Therefore it must implement some kind of userland threads or tasks, which can be achieved with an event loop (at least partly) to schedule new tasks.
Let's take the following Javascript code:
console.log('hello1');
setTimeout(() => console.log('hello2'), 0);
console.log('hello3');
setTimeout(() => console.log('hello4'), 0);
console.log('hello5');
The output will be
hello1
hello3
hello5
hello2
hello4
How can I do this in tokio? Is tokio meant to work like this overall? I tried the following code
async fn set_timeout(f: impl Fn(), ms: u64) {
tokio::time::sleep(tokio::time::Duration::from_millis(ms)).await;
f()
}
#[tokio::main]
async fn main() {
println!("hello1");
tokio::spawn(async {set_timeout(|| println!("hello2"), 0)}).await;
println!("hello3");
tokio::spawn(async {set_timeout(|| println!("hello4"), 0)}).await;
println!("hello5");
}
The output is just
hello1
hello3
hello5
If I change the code to
println!("hello1");
tokio::spawn(async {set_timeout(|| println!("hello2"), 0)}.await).await;
println!("hello3");
tokio::spawn(async {set_timeout(|| println!("hello4"), 0)}.await).await;
println!("hello5");
The output is
hello1
hello2
hello3
hello4
hello5
but then I don't get the point of the whole async/await/future feature, because then my "async" set_timeout-tasks are actually blocking the other println statements..