Yew v0.19中如何将Callback用作wasm_bindgen Closure
本问题针对Yew v0.19版本编写
核心问题场景
Rust中可通过Closure传入函数,实现异步外部JavaScript函数的调用,基础用法示例如下:
#[wasm_bindgen] extern "C" { fn setInterval(closure: &Closure<dyn FnMut()>, time: u32) -> i32; } // ... let cb = Closure::new(|| { log("interval elapsed!"); }); let interval_id = setInterval(&cb, 1_000);
上述示例逻辑清晰,但Closure存在一项核心约束:传入的函数必须满足'static生命周期要求。在Yew应用中,实现自发事件响应的标准机制是Message枚举,通过update()方法更新Model状态;但Context中负责发送消息的link()机制并不具备静态生命周期。
理想场景下,闭包接收到的返回值可直接作为Yew组件消息提交,对应实现代码如下:
struct Model { thing: Option<JsValue>, } enum Msg { GotThing(JsValue), } #[wasm_bindgen] extern "C" { fn createThing(closure: &Closure<dyn FnMut(JsValue) -> ()>); } impl Component for Model { type Message = Msg; type Properties = (); fn create(_ctx: &Context<Self>) -> Self { Model { thing: None, // initial value } } fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> bool { match msg { Msg::GotThing(x) => { // handle the message self.thing = Some(x); true }, } } fn rendered(&mut self, ctx: &Context<Self>, first_render: bool) { if first_render { let cb: Box<dyn FnMut(JsValue) -> ()> = Box::new(|x| { // try and issue the message ctx.link().send_message(Msg::GotThing(x)); // ^ doesn't have a `'static` lifetime! Won't compile }); createThing(Closure::wrap(&cb)); } } // fn view() ... omitted, not relevant }
待确认诉求
- 是否存在将
Callback转换为Closure的可行方案,或是更符合Yew设计规范的标准实现方式 - 曾考虑通过静态定义的队列作为传入
createThing的Closure与组件内部消息派发之间的中介结构,实现组件内的消息正常派发,但可变静态变量存在安全风险,想确认是否存在尚未注意到的Yew组件外部交互方式 - 明确解决该问题的最规范实现方案
内容的提问来源于stack exchange,提问作者Athan Clark
相关产品推荐
相关产品推荐

