Closed
Description
Picking up from #1126
Consider the following:
use futures::{Future, Async, Poll};
use futures::sync::oneshot::{Sender, Receiver, channel};
use futures::task::current;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use web_sys::*;
struct AsyncCounter {
value: f64,
target: f64,
state: CounterState,
}
enum CounterState {
Init,
Counting { err_receiver: Receiver<JsValue> },
Error (JsValue)
}
impl Future for AsyncCounter {
type Item = JsValue;
type Error = JsValue;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match &self.state {
CounterState::Init => {
//Setup callback for updates
let (err_sender, err_receiver):(Sender<JsValue>, Receiver<JsValue>) = channel();
let task = current();
let closure = Closure::wrap(Box::new(move || {
//This is not allowed
err_sender.send(JsValue::from_str("foo"));
task.notify();
}) as Box<FnMut()>);
// TODO: handle cancellation with clearTimeout
window().unwrap().set_timeout_with_callback_and_timeout_and_arguments_0(closure.as_ref().unchecked_ref(), 1000).unwrap();
//Move to counting state
self.state = CounterState::Counting {err_receiver} ;
let task = current();
task.notify();
Ok(Async::NotReady)
},
CounterState::Counting {err_receiver} => {
if self.value == self.target {
Ok(Async::Ready(JsValue::from_f64(self.value as f64)))
} else {
self.value += 1.0;
Ok(Async::NotReady)
}
},
CounterState::Error (err) => {
Err(err.clone())
}
}
}
}
If I remove that line: err_sender.send(JsValue::from_str("foo"));
then it compiles fine. But with that line, I can't seem to get around the trait constraints.
Any tips?
(I've left out the receiver polling just to keep the example a bit more concise - but we can imagine that polling it could move the state to CounterState::Error
)
Metadata
Metadata
Assignees
Labels
No labels