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

Yew项目异步请求数据及解决“use of moved value”错误

问题分析与解决方案

错误原因

你的代码存在两个核心问题:

  1. 所有权转移冲突:async move闭包会捕获games_tonight的所有权,函数末尾试图返回该变量时,编译器报错“use of moved value”——变量已被移至闭包内,当前作用域不再拥有它的所有权。
  2. 异步执行逻辑错误:spawn_local是异步调度任务,函数get_sched会立刻返回初始的空Vec,不会等待异步请求完成。就算解决所有权问题,返回的也只会是未填充数据的空集合。

Yew项目的正确实现方式

Yew是响应式组件框架,异步数据加载需要和组件状态绑定,通过状态更新触发UI重渲染。以下是标准实现方案:

代码示例

use yew::prelude::*;
use wasm_bindgen_futures::spawn_local;

// 假设你已定义好这些类型
#[derive(Debug, Clone)]
struct MyObj {
    // 你的字段定义
}

#[derive(Debug, serde::Deserialize)]
struct myStruct {
    dates: Vec<DateData>,
}

#[derive(Debug, serde::Deserialize)]
struct DateData {
    games: Vec<GameRaw>,
}

#[derive(Debug, Clone, serde::Deserialize)]
struct GameRaw {
    // API返回的游戏原始字段
}

#[function_component(ScheduleComponent)]
pub fn schedule_component() -> Html {
    // 用use_state创建响应式状态,存储加载后的游戏数据
    let games_tonight = use_state(|| Vec::new());

    // 组件挂载时发起异步请求
    use_effect_with_deps(move |_| {
        // 克隆状态句柄,避免闭包捕获原句柄的所有权
        let games_handle = games_tonight.clone();
        
        spawn_local(async move {
            // 处理请求与解析,避免unwrap导致panic
            match Request::get("http://...url...").send().await {
                Ok(response) => {
                    match response.json::<myStruct>().await {
                        Ok(api_data) => {
                            let mut parsed_games = Vec::new();
                            // 遍历API返回的游戏数据,转换为MyObj
                            for raw_game in api_data.dates[0].games.to_owned() {
                                parsed_games.push(MyObj {
                                    // 填充你的MyObj字段逻辑
                                });
                            }
                            // 更新状态,触发组件重渲染
                            games_handle.set(parsed_games);
                        }
                        Err(json_err) => {
                            web_sys::console::log_1(&format!("JSON解析失败: {:?}", json_err).into());
                        }
                    }
                }
                Err(req_err) => {
                    web_sys::console::log_1(&format!("API请求失败: {:?}", req_err).into());
                }
            }
        });

        // 清理函数(此处无需清理,返回空闭包)
        || ()
    }, ()); // 依赖为空,仅在组件首次挂载时执行

    // 根据状态渲染UI
    html! {
        <div class="schedule-container">
            {if games_tonight.is_empty() {
                html! { <p>{"加载赛事数据中..."}</p> }
            } else {
                html! {
                    <ul class="game-list">
                        {for games_tonight.iter().map(|game| {
                            html! { <li>{/* 渲染单个MyObj的内容 */}</li> }
                        })}
                    </ul>
                }
            }}
        </div>
    }
}

关键要点

  • 响应式状态:用use_state创建可更新的状态,调用set方法时,Yew会自动触发组件重渲染,展示最新数据。
  • 副作用处理:use_effect_with_deps专门用于处理异步请求这类副作用,依赖参数为空时,仅在组件挂载时执行一次请求。
  • 错误处理:替换unwrap为match分支,避免请求或解析失败时直接panic,同时在控制台打印错误信息便于调试。
  • 所有权管理:克隆状态句柄(games_tonight.clone())后传入异步闭包,既保证能更新状态,又不会影响原作用域的变量所有权。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 19:20:37