如何在Yew中使用异步函数作为yew::callback::Callback?
在Yew中使用异步函数作为Callback的解决方案
问题场景
我在Yew中为onsubmit事件注册了如下Callback:
use gloo::net::http::Request; use yew::prelude::*; let on_submit = Callback::from(async move |ev: FocusEvent| { ev.prevent_default(); let res = Request::post("https://formsubmit.co/srineshnisala@gmail.com") .send() .await .unwrap(); assert_eq!(res.status(), 200); });
但使用async时触发了以下编译错误:
--> src/pages/contact/contact.rs:26:36 | 26 | let on_submit = Callback::from(async move |ev: FocusEvent| { | _____________________--------------_^ | | | | | required by a bound introduced by this call 27 | | ev.prevent_default(); 28 | | 29 | | let res = Request::post("https://formsubmit.co/srineshnisala@gmail.com") ... | 34 | | assert_eq!(res.status(), 200); 35 | | }); | |_____^ expected `()`, found opaque type | ::: /home/s1n7ax/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/future/mod.rs:72:43 | 72 | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return> | ------------------------------- the found opaque type | = note: expected unit type `()` found opaque type `impl Future<Output = ()>` = note: required for `yew::Callback<yew::FocusEvent>` to implement `From<[closure@src/pages/contact/contact.rs:26:36: 26:63]>`
使用的环境版本:
- Rust版本:
rustc 1.66.0-nightly (01af5040f 2022-10-04) - 依赖包版本:
yew = "0.19.3" yew-router = "0.16.0" gloo = "0.7.0" # console log and stuff hyper = "0.14.19" # http requests
解决方案
Yew的Callback要求传入的闭包返回值为(),但异步闭包会返回impl Future<Output = ()>类型,这与Callback的类型要求不匹配,从而导致编译错误。要解决这个问题,需要将异步逻辑包裹在wasm_bindgen_futures::spawn_local函数中,让异步任务在浏览器的事件循环中执行,外层闭包则返回()以符合Callback的要求。
修改后的代码
use gloo::net::http::Request; use wasm_bindgen_futures::spawn_local; use yew::prelude::*; let on_submit = Callback::from(move |ev: FocusEvent| { ev.prevent_default(); // 将异步任务提交到本地事件队列执行 spawn_local(async move { let res = Request::post("https://formsubmit.co/srineshnisala@gmail.com") .send() .await .unwrap(); assert_eq!(res.status(), 200); }); });
补充说明
- 需要在
Cargo.toml中添加wasm-bindgen-futures依赖:
wasm-bindgen-futures = "0.4"
spawn_local的作用是将异步任务绑定到WebAssembly的本地事件循环,确保异步代码能够被正确调度执行,同时不会阻塞主线程。
内容的提问来源于stack exchange,提问作者s1n7ax
相关产品推荐
相关产品推荐

