Rust/wasm/async sleeping for 100 milli seconds goes up to 1 minute

    pub async fn sleep(millis: i32) {
        let mut cb = |resolve: js_sys::Function, _reject: js_sys::Function| {
            web_sys::window()
                .unwrap()
                .set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, millis)
                .unwrap();};
        let p = js_sys::Promise::new(&mut cb);
        wasm_bindgen_futures::JsFuture::from(p).await.unwrap();}

usage:

            let t_0 = instant::Instant::now();
            Util::sleep(100).await;
            let t_1 = instant::Instant::now();

            console_log!("slept for {:?}, woke up; checking mailbox", t_1 - t_0);

I'm expecting this to output timings of near 100ms

Instead, I get timings of: (timings are noisy, but within 5% of listed below)

300ms
1000ms
1000ms
1000ms
20s
60s
60s
60s
60s
60s
60s

Is there anything wrong with my sleep impl above? I am getting the impression that it is failing to inform the async runtime that it is time to wake up.

Is this happening in a background browser tab by any chance? Browsers intentionally do this to all timers when the tab is in the background.

5 Likes

This is insane debugging. I had two (nearly) identical tabs open, expected no dom nodes for either, had chrome dev tools attached to the one in the background, and yeah, spot on.