我想为 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()
),那就不再起作用了。
有两种选择:
然而,最好的策略实际上是两者都不做,而是做你认为很黑客的事情 -
setInterval()
。这是因为日志发出的速度非常快,而从 WASM 调用 JS 甚至更多写入 DOM 的速度非常慢,因此如果您对每个日志记录都这样做,这会损害您的速度。您只希望以恒定的速率获得,因为无论如何人眼都无法分辨出差异。