-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mark js_sys::Promise as #[must_use] #1927
Conversation
To be clear, JS Promises are always eager, which means they always run immediately. So even if you immediately discard the Promise, the computation (and side effects) will still happen. So there are legitimate reasons for discarding Promises. Having said that, I'm in favor of this change, since it helps to prevent bugs (especially bugs with error handling), and users can always do |
Thanks for clarifying that! The few places I had to silence the warnings after this change make more sense to me now. |
Sounds reasonable to me, thanks @darinmorrison! |
I recently ran into this warning about having to use a Or perhaps I'm missing something and there is something better to do with my unused |
I don't think there is anything wrong with using |
Sure. I have my (simplified) module using fetch below: use std::sync::Arc;
use wasm_bindgen::{JsCast, JsValue};
use wasm_bindgen::closure::Closure;
use web_sys::console;
/// Used to fetch buffers at a fixed URL, using web_sys.
pub struct Fetcher {
base_url: String,
}
impl Fetcher {
pub fn new(base_url: String) -> Self {
Self { base_url }
}
pub fn fetch<F>(&self, label: &str, finish: F)
where
F: 'static + FnOnce(Arc<[u8]>),
{
let window = match web_sys::window() {
Some(w) => w,
None => return,
};
let url = format!("{}/{}", self.base_url, label);
console::log_2(&"url".into(), &url.clone().into());
let resolve = Closure::once(move |resp: JsValue| {
console::log_1(&"resolved".into());
let resp: web_sys::Response = resp.dyn_into().unwrap();
let resolve = Closure::once(move |array: JsValue| {
let array = js_sys::Uint8Array::new(&array);
finish(array.to_vec().into());
});
let _ = resp.array_buffer().unwrap().then(&resolve);
resolve.forget();
});
let reject = Closure::once(move |resp: JsValue| {
console::log_2(&"rejected".into(), &resp);
});
let _ = window.fetch_with_str(&url).then2(&resolve, &reject);
resolve.forget();
reject.forget();
}
} |
@zachreizner Thanks for providing an example. I think part of the issue here is that programming directly with Here is an attempt to rewrite your example using use wasm_bindgen::{prelude::*, JsCast, JsValue};
use wasm_bindgen_futures::JsFuture;
use web_sys::console;
/// Used to fetch buffers at a fixed URL, using web_sys.
pub struct Fetcher {
base_url: String,
}
impl Fetcher {
pub fn new(base_url: String) -> Self {
Self { base_url }
}
pub async fn fetch<F>(&self, label: &str) -> Result<js_sys::Uint8Array, JsValue> {
let window = web_sys::window().unwrap_throw();
let url = format!("{}/{}", self.base_url, label);
console::log_2(&"url".into(), &url.clone().into());
let promise = window.fetch_with_str(&url);
let future = JsFuture::from(promise);
match future.await {
Ok(resp) => {
console::log_1(&"resolved".into());
let resp: web_sys::Response = resp.dyn_into().unwrap();
let buffer = resp.array_buffer()?;
let buffer = JsFuture::from(buffer).await?;
let array = js_sys::Uint8Array::new(&buffer);
Ok(array)
}
Err(resp) => {
console::log_2(&"rejected".into(), &resp);
Err(resp)
}
}
}
} |
@darinmorrison Thanks for responding to my example so thoroughly. My original version of this fetch method actually did use If I were to follow your example, I'm unsure how I would actually go about executing the async future without |
I originally opened an issue about this at rust-lang/rust-clippy#4936. Please look there for the rationale.