Rust: setTimeout and setInterval as in Javascript with “tokio” as Runtime

Published by Philipp Schuster on

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.

warning 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. warning

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;
}

Philipp Schuster

Hi, I'm Philipp and interested in Computer Science. I especially like low level development, making ugly things nice, and de-mystify "low level magic".

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *