异步操作
2026/5/21小于 1 分钟euvuirustwasmusage-introductionasync
异步数据获取
use euv::*;
let loading: Signal<bool> = use_signal(|| false);
let loading_updater: Signal<bool> = loading;
let data: Signal<String> = use_signal(|| "".to_string());
let data_updater: Signal<String> = data;
let error: Signal<String> = use_signal(|| "".to_string());
let error_updater: Signal<String> = error;
button {
onclick: move |_event: Event| {
loading_updater.set(true);
error_updater.set("".to_string());
let data_updater_clone: Signal<String> = data_updater;
let loading_updater_clone: Signal<bool> = loading_updater;
let error_updater_clone: Signal<String> = error_updater;
spawn_local(async move {
let window: Window = window().expect("no global window exists");
let promise: Promise = window.fetch_with_str("https://httpbin.org/get");
let future: JsFuture = JsFuture::from(promise);
match future.await {
Ok(response) => {
let resp: Response = response.dyn_into().unwrap();
let json_promise: Promise = resp.json().unwrap();
let json_future: JsFuture = JsFuture::from(json_promise);
match json_future.await {
Ok(json) => {
let json_string: String = JSON::stringify(&json).unwrap().as_string().unwrap_or_default();
data_updater_clone.set(json_string);
}
Err(_) => {
error_updater_clone.set("Failed to parse JSON".to_string());
}
}
}
Err(_) => {
error_updater_clone.set("Network request failed".to_string());
}
}
loading_updater_clone.set(false);
});
}
"Fetch Data"
}提示
使用 spawn_local(euv 重新导出的 wasm_bindgen_futures::spawn_local)在 WASM 中执行异步任务,任务完成后通过信号更新 UI。JsFuture、JSON、Promise、Window、Response 等类型均通过 use euv::* 可用,无需单独引入 js-sys 或 web-sys。
注意
异步闭包中使用的信号必须在闭包外克隆一份再移入,否则会导致借用冲突。