Rust: setTimeout and setInterval as in Javascript with “tokio” as Runtime
Even though I’m working with Rust for over 2.5 years now, I unfortunately never made a deep dive into the async/await/future
-world. But I started using tokio a few days ago and a few questions came up. Tokio
is a runtime for executing futures, great! For this, tokio
needs some kind of “tasks” or “lightweight userland threads”, okay. To schedule N
tasks across M
cores, tokio
need some kind of event loop,.. so.. similar to Javascript?!
I didn’t look into the code but it has to work somehow like this. Because Javascript is the only language where I used async/await
more or less intensively, I wondered: if Javascript has an event loop and setTimeout()
and setInterval()
work because of this event loop, than it must be possible to achieve similar behavior in tokio
. I created a small crate for this. It helped me a lot to better understand how futures
in Rust work and how the tokio
runtime executes them.
The library is public and available on crates.io and github.
I’m not an expert in tokio
(or async/await/futures
in Rust in general) yet and I don’t know if this follows best practises. But it helped me to understand how tokio
works. I hope it may be helpful to some of you too.
Example Code
Javascript Example we want to rewrite to Rust/Tokio
console.log('hello1'); setTimeout(() => console.log('hello2'), 0); console.log('hello3'); setTimeout(() => console.log('hello4'), 0); console.log('hello5');
This will output
hello1
hello3
hello5
hello2
hello4
Rust Code
To get a similar behaviour in Rust with tokio
, use the following code, that benefits from my library.
// also add 'tokio-js-set-interval = "<latest-version>"' to your Cargo.toml! use std::time::Duration; use tokio_js_set_interval::{set_interval, set_timeout}; #[tokio::main] async fn main() { println!("hello1"); set_timeout!(println!("hello2"), 0); println!("hello3"); set_timeout!(println!("hello4"), 0); println!("hello5"); // give enough time before tokios runtime exits tokio::time::sleep(Duration::from_millis(1)).await; }
0 Comments