How to get a value out of a wasm_bindgen_futures::spawn_local
Asked Answered
F

3

6

I know that wasm doesn't have blocking so how would I do the equivalent. Or is there a different tool to use? I'm new to this so it could also be that my approach is completely off. I'm using wasm-pack with a web target to compile.

fn fetch_definitions(def_dir: &str, spelling: &str) -> Result<WordDefs, Error> {
    let path = format!("{def_dir}/{spelling}_definitions.json");

    let r = wasm_bindgen_futures::spawn_local(async move {
        let response: WordDefs = gloo_net::http::Request::get(path.as_str())
            .send()
            .await
            .unwrap()
            .json()
            .await
            .unwrap();
    });

    // what I would normally do to  get a value from a future
    // let value = executor::block_on(r);

    Err(Error::CouldNotLookUpWord)
}

As I know I have to use wasm_bindgen_futures for the async block and spawn_local has output=(), I can figure out how to get around this.

Fulton answered 7/6, 2023 at 2:46 Comment(0)
C
1

I guess you are using Yew with wasm_bindgen_futures ?

    use wasm_bindgen_futures::spawn_local;

the solution here is for Yew == 0.21.0

    pub enum Msg 
    {
    
        ResultFromSpawn ( WordDefs ), // WordDefs is the result from your spwan_local
    
        //... your other Msgs,
    }



    fn fetch_definitions( ctx: &Context<Self> ... your other params .. ) -> Result<WordDefs, Error> 
    {
        //.. your stuffs
    
        let link = ctx.link().clone();   // this is where you get link from ctx
    
        // I removed let r = ..  from your original code
        wasm_bindgen_futures::spawn_local( async move 
        {
            let response: WordDefs = gloo_net::http::Request::get(path.as_str())
                .send()
                .await
                .unwrap()
                .json()
                .await
                .unwrap();
    
            link.sendMessage( Msg::ResultFromSpawn( response ) );  // use "link" to pass data to Msg 
        });
    
        //... your stuffs
    }

then you can process Msg as usual in update function as below;

    fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> bool 
    { 
        match msg 
        {
            Msg::ResultFromSpawn( response ) => 
            {
               // process your response ( type of WordDefs ) here 
            }
    
            // other Msgs
        } 
    }
Charissa answered 26/3 at 7:20 Comment(0)
D
0

This isn't possible due to the single threaded nature of browsers, see this issue for more info.

Dunaway answered 24/7, 2023 at 15:59 Comment(0)
J
0

I think we can use async-std crate with "unstable" feature like:

let r = async_std::task::spawn_local(async move {
        let response: WordDefs = gloo_net::http::Request::get(path.as_str())
            .send()
            .await
            .unwrap()
            .json()
            .await
            .unwrap();
    });
Johm answered 5/1 at 17:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.