Gerando Futures

Os "hooks" use_future e use_coroutine são úteis se você quiser gerar incondicionalmente o Future. Às vezes, porém, você desejará apenas gerar um Future em resposta a um evento, como um clique do mouse. Por exemplo, suponha que você precise enviar uma solicitação quando o usuário clicar em um botão "log in". Para isso, você pode usar cx.spawn:


#![allow(unused)]
fn main() {
    let logged_in = use_state(cx, || false);

    let log_in = move |_| {
        cx.spawn({
            let logged_in = logged_in.to_owned();

            async move {
                let resp = reqwest::Client::new()
                    .post("http://example.com/login")
                    .send()
                    .await;

                match resp {
                    Ok(_data) => {
                        println!("Login successful!");
                        logged_in.set(true);
                    }
                    Err(_err) => {
                        println!(
                            "Login failed - you need a login server running on localhost:8080."
                        )
                    }
                }
            }
        });
    };

    cx.render(rsx! {
        button {
            onclick: log_in,
            "Login",
        }
    })
}

Nota: spawn sempre gerará um novo Future. Você provavelmente não quer chamá-lo em cada renderização.

O Future deve ser 'static – então quaisquer valores capturados pela tarefa não podem carregar nenhuma referência a cx, como um UseState.

No entanto, como você normalmente precisa de uma maneira de atualizar o valor de um gancho, você pode usar to_owned para criar um clone do handle do hook. Você pode então usar esse clone no encerramento assíncrono.

Para tornar isso um pouco menos detalhado, o Dioxus exporta a macro to_owned! que criará uma ligação como mostrado acima, o que pode ser bastante útil ao lidar com muitos valores.


#![allow(unused)]
fn main() {
        use dioxus::hooks::to_owned;

        cx.spawn({
            to_owned![count, age, name, description];
            async move {
                // ...
            }
        });
}

Calling spawn will give you a JoinHandle which lets you cancel or pause the future.

Gerando Tarefas do Tokio

Às vezes, você pode querer gerar uma tarefa em segundo plano que precise de vários threads ou conversar com o hardware que pode bloquear o código do seu aplicativo. Nesses casos, podemos gerar diretamente uma tarefa Tokio do nosso Future. Para Dioxus-Desktop, sua tarefa será gerada no tempo de execução Multi-Tarefado do Tokio:


#![allow(unused)]
fn main() {
        cx.spawn(async {
            let _ = tokio::spawn(async {}).await;

            let _ = tokio::task::spawn_local(async {
                // some !Send work
            })
            .await;
        });
}