Open olanod opened 3 years ago
This would be awesome! Would it be possible to have the opposite too i.e. subscribe to a Rust Stream
from Javascript via the registration of a callback/RxJS Observable or similar? Apologies in advance if this has an obvious solution, I am at the beginning of my journey with Rust...
I know already that you can call pre-existing global/static JS functions from Rust via an extern "C"
block. However, it would be great to be able to manage subscriptions dynamically. I tried passing in a &js_sys::Function
callback, but I couldn't get the callback to survive longer than the registration function:
use std::collections::HashMap;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Default)]
pub struct Subscribable<'a> { // compiler error that lifetimes aren't available
xs: Vec<u32>,
subscribers: HashMap<u32, &'a js_sys::Function>,
next_id: u32,
}
#[wasm_bindgen]
impl Subscribable {
pub fn new() -> Self {
Self {
xs: vec![1, 2, 3],
subscribers: HashMap::new(),
next_id: 0,
}
}
pub fn each(&self, callback: &js_sys::Function) {
let this = JsValue::null();
for &x in &self.xs {
let x = JsValue::from(x);
callback.call1(&this, &x);
}
}
// subscriber can't survive past the end of this method
pub fn subscribe(&mut self, subscriber: &js_sys::Function) -> u32 {
let id = self.next_id;
self.subscribers.insert(id, subscriber);
self.next_id += 1;
id
}
pub fn unsubscribe(&self, subscription: u32) {
self.subscribers.remove(&subscription);
}
}
Any pointers would be hugely appreciated!
@mattgibb Hi! Did you ever figure out how to do this? I'm at the same point now, having streams in Rust that I want to react to in JS, without a separate global listener function import. Either with callbacks like your code above, or by converting to an AsyncIterator.
@mattgibb你好!你有想过如何做到这一点吗?我现在处于同一点,在 Rust 中有流,我想在 JS 中做出反应,而不需要单独的全局侦听器函数导入。使用像上面的代码这样的回调,或者转换为 AsyncIterator。
+1
AsyncIterator
in JS is the native equivalent of Promise to represent multiple future values instead of one just as in Rust we haveFuture
andStream
(soon in the standard library). Instead of creating a separate utility crate that converts async iterators to Rust streams I propose having that in function(e.g.iter_to_stream
) in thewasm-bindgen-futures
crate since the feature(can be behind a flag) is very "futures" related.