You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dioxus 0.5中spawn函数未执行异步代码的问题排查

问题

使用Dioxus 0.5开发桌面应用时,组件中的spawn函数无法执行内部异步代码。代码编译正常无报错,点击按钮后无预期效果,但use_future或从事件处理器返回Future等其他异步方法可正常工作,且符合Dioxus文档的使用场景。

提交表单时能看到Creating user和父组件onsubmit回调中的Refreshing publishers,但看不到Inside spawn,用户也未创建(service方法正确,之前用use_future可正常工作)。

失效组件代码

use crate::logic::models::{Gender, Publisher};
use crate::logic::publishers_service;
use crate::AppState;
use dioxus::prelude::*;

#[component]
pub fn AddPublisherForm(onsubmit: EventHandler<()>) -> Element {
    let onsubmit = move |evt: Event<FormData>| {
        let vals = evt.data.values();
        let name = vals.get("name");

        let gender_string = vals.get("gender").unwrap().as_value();
        let gender = match gender_string.as_str() {
            "m" => Gender::Male,
            "f" => Gender::Female,
            _ => Gender::Male,
        };

        let suspended = vals.get("suspended").is_some();

        if name.is_none() {
            return ();
        }

        let name = name.unwrap().as_value();
        let state = use_context::<Signal<AppState>>();

        println!("Creating user");

        spawn(async move {
            println!("Inside spawn");
            publishers_service::create(
                Publisher {
                    id: None,
                    name: name.clone(),
                    gender,
                    suspended,
                },
                &state(),
            )
            .await;
        });

        onsubmit.call(());
    };

    rsx! {
        div {
            form {
                onsubmit: onsubmit,

                fieldset {
                    legend {
                        "Add publiser"
                    },

                    input {
                        name: "name"
                    },

                    "male",

                    input {
                        r#type: "radio",
                        name: "gender",
                        value: "m",
                        checked: true
                    },

                    "female",

                    input {
                        r#type: "radio",
                        name: "gender",
                        value: "f",
                        checked: false
                    }

                    "suspended",
                    input {
                        r#type: "checkbox",
                        name: "suspended",
                        checked: false
                    }

                    button {
                        "create"
                    }
                }
            }
        }
    }
}

相关初始化代码

main.rs 数据库连接准备

#[derive(Clone)]
pub struct AppState {
    connection: Pool<Sqlite>,
}

fn main() -> Result<()> {
    let rt = Runtime::new().unwrap();
    let handle = rt.handle();

    let db = handle.block_on(async { create_db().await });

    let state = AppState { connection: db };

    launch_app(state);

    Ok(())
}

应用启动代码

pub fn launch_app(state: AppState) {
    // Init logger
    dioxus_logger::init(Level::INFO).expect("failed to init logger");

    LaunchBuilder::desktop()
        .with_cfg(
            Config::default()
                .with_custom_head("<link href=\"./base.css\" rel=\"stylesheet\">".to_string())
                .with_menu(None),
        )
        .with_context(state)
        .launch(App);
}
分析与解决

核心原因:自定义Runtime与Dioxus的Runtime冲突

你在main函数中手动创建了tokio::Runtime,但Dioxus桌面应用会自动初始化自己的Runtime环境。手动创建的Runtime并未被Dioxus的spawn函数使用,导致你通过spawn提交的异步任务没有合适的执行上下文,无法启动。

另外,use_future能正常工作是因为它绑定到了Dioxus自身的Runtime上,而你手动创建的Runtime只在初始化数据库时被使用,和后续组件的异步任务无关。

解决步骤

1. 移除手动创建的Runtime

不需要在main中手动初始化tokio Runtime,Dioxus会自动处理。修改main函数如下:

fn main() -> Result<()> {
    let db = dioxus::tokio::block_on(async { create_db().await });
    let state = AppState { connection: db };

    launch_app(state);

    Ok(())
}

2. 拦截表单默认行为(可选但推荐)

当前代码未阻止表单的默认提交行为,可能导致不必要的重渲染干扰。建议在事件处理器开头添加:

evt.prevent_default();

3. 验证spawn行为

移除自定义Runtime后,Dioxus会自动将spawn的任务调度到正确的执行上下文,此时Inside spawn日志和数据库创建操作就能正常执行。

内容的提问来源于stack exchange,提问作者Drago96

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 06:38:12