Skip to content

async yield function #3359

Closed as not planned
Closed as not planned
@emilk

Description

@emilk

I have a task where I need to decode a bunch of messages from a stream. Every 10ms I want to yield to my UI task (running on requestAnimationFrame). My code is something like this:

async fn decode_in_chunks(
    mut decoder: Decoder,
    process: Box<dyn Fn(Message)>,
) {
    let mut last_yield = instant::Instant::now();
    
    for msg in decoder {
        process(msg);

        if last_yield.elapsed() > instant::Duration::from_millis(10) {
            // yield to the ui task
            yield_().await;
            last_yield = instant::Instant::now();
        }
    }
}

I spawn this with wasm_bindgen_futures::spawn_local

The problem is the yield_ function. I've currently defined it as so:

/// Yield to other tasks
async fn yield_() {
    sleep_ms(1).await;
}

// Hack to get async sleep on wasm
async fn sleep_ms(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)
            .expect("Failed to call set_timeout");
    };
    let p = js_sys::Promise::new(&mut cb);
    wasm_bindgen_futures::JsFuture::from(p).await.unwrap();
}

this feels very hacky, for obvious reasons.

Any suggestions for how to improve this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions