“流”消息从 Rust 到 javascript

问题描述 投票:0回答:1

我想为 log create 实现一个记录器,它允许我将消息流式传输/异步发布到 JavaScript,以便将它们显示给用户。

目前,我有一个非常简单的设置,需要 JavaScript“询问”日志,这不是最佳选择,因为我并不真正处于上下文中,我只想在完成某件事后显示日志,但是当它发生的时候。

static LOGGER: Logger = Logger::new();

#[wasm_bindgen]
pub struct Logger {
    logs: Mutex<Vec<String>>,
    level: Mutex<LogLevel>,
}

impl Logger {
    pub fn init_once() {
        static INIT: Once = Once::new();
        INIT.call_once(|| {
            log::set_logger(&LOGGER).unwrap();
            log::set_max_level(log::LevelFilter::max());
        })
    }
}

#[wasm_bindgen]
impl Logger {
    pub fn get_logs() -> Vec<String> {
        let logs = LOGGER
            .logs
            .lock()
            .expect("failed to acquire a lock to logger while getting logs");

        logs.clone()
    }
}

我尝试添加

add_log_listener
remove_log_listener
方法,但发现这不起作用,因为
js_sys::Function
在某些时候是
*mut u*
(我猜是某种指针?对于出于某种原因它是
*mut
?),它没有实现
Send
,这是
log::Log
特性所需要的。

我对 API 应该如何工作没有任何特定的愿景,只要日志可以以异步方式显示即可:)


PS: 显示当前由 Monaco Editor 完成,因此仅传递 HTML 元素并附加到它并不是那么容易。而且我也不确定这是否会更加线程安全。还没有深入研究过。而且我真的希望显示逻辑不一定与我的日志逻辑混合......如果可能的话。

我还考虑过使用 JavaScript 中的

setInterval
来轮询记录器,但这听起来很老套。我认为,现在这应该不是问题,但是一旦有多个东西调用
get_logs()
(因此
clear_logs()
),那就不再起作用了。

rust wasm-pack
1个回答
0
投票

有两种选择:

  • 将回调存储在本地线程中。除非你实际使用 WASM 线程(无论如何都不稳定),否则这将是相同的。
  • 创建一个拥有回调的特定线程,并通过通道向其发送事件。

然而,最好的策略实际上是两者都不做,而是做你认为很黑客的事情 -

setInterval()
。这是因为日志发出的速度非常快,而从 WASM 调用 JS 甚至更多写入 DOM 的速度非常慢,因此如果您对每个日志记录都这样做,这会损害您的速度。您只希望以恒定的速率获得,因为无论如何人眼都无法分辨出差异。

© www.soinside.com 2019 - 2024. All rights reserved.