dioxus
dioxus copied to clipboard
Using recv in js inside an eval on desktop blocks all js if it doesnt have any data to fetch
Problem
Currently when you do eval("await dioxus.recv();")
on desktop and dont send a message it blocks all js from running, including devtool console and events.
Steps To Reproduce
Heres the code i used to test it
#![allow(non_snake_case)]
use dioxus::{desktop::use_window, prelude::*};
use log::LevelFilter;
fn main() {
// Init debug
dioxus_logger::init(LevelFilter::Info).expect("failed to init logger");
dioxus::launch(App);
}
#[component]
fn App() -> Element {
// Build cool things ✌️
let windows = use_window();
use_hook(|| windows.devtool());
let mut signal = use_signal(|| false);
use_effect(move || {
if signal() {
eval(
r#"
window.alert("1");
await dioxus.recv();
window.alert("2");
"#,
);
}
});
let onclick = move |_| signal.with_mut(|v| *v = !*v);
rsx! {
button {
onclick,
"locks js"
}
{format!("{}", signal())}
}
}
Environment:
- Dioxus version: 0.5.1
- Rust version: 1.76.0
- OS info: MacOS
- App platform: desktop
Questionnaire
- [ ] I'm interested in fixing this myself but don't know where to start
- [ ] I would like to fix and I have a solution
- [ ] I don't have time to fix this right now, but maybe later
as far as i understand it the offending code is the infinite loop in the timeout here in query.rs
recv: function () {
return new Promise((resolve, _reject) => {
// Ever 50 ms check for new data
let timeout = setTimeout(() => {
let __msg = null;
while (true) {
let __data = _message_queue.shift();
if (__data) {
__msg = __data;
break;
}
}
clearTimeout(timeout);
resolve(__msg);
}, 50);
});
},
the above timeout should likely be changed to an interval without the inner loop instead
not directly related but it should probably be cleaned up when dropping UseEval
as well