4个版本
0.1.3 | 2024年7月11日 |
---|---|
0.1.2 | 2023年11月11日 |
0.1.1 | 2023年11月3日 |
0.1.0 | 2023年11月3日 |
在异步分类中排名第240
每月下载量55次
23KB
132 行
async-event-emitter
async-event-emitter是event-emitter-rs
crate的异步实现
允许您通过回调函数订阅事件并触发这些事件。事件形式为(字符串,值),回调函数形式为接受值参数的闭包;
与event-emitter-rs
的差异
- 发射的值应实现一个额外的特质(Debug),除了Serde的Serialize和Deserialize。
- 这是一个异步实现,不仅限于tokio,但在
use-async-std
功能标志下支持async-std。 - 监听器方法(on和once)接受一个返回未来的回调,而不仅仅是闭包。
- emit方法通过创建tokio任务而不是std::thread在每个事件上执行每个回调
入门指南
use async_event_emitter::AsyncEventEmitter;
#[tokio::main]
async fn main() {
let mut event_emitter = AsyncEventEmitter::new();
// This will print <"Hello world!"> whenever the <"Say Hello"> event is emitted
event_emitter.on("Say Hello", |_: ()| async move { println!("Hello world!") });
event_emitter.emit("Say Hello", ()).await.unwrap();
// >> "Hello world!"
}
基本用法
只要它们实现Debug特质和serde的Serialize和Deserialize特质,我们就可以发出和监听任何类型的值。单个EventEmitter实例可以监听多种类型的值。
use async_event_emitter::AsyncEventEmitter as EventEmitter;
use serde::{Deserialize, Serialize};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut event_emitter = EventEmitter::new();
event_emitter.on("Add three", |number: f64| async move {
println!("{}", number + 3.0)
});
event_emitter.emit("Add three", 5.0_f64).await?;
event_emitter.emit("Add three", 4.0_f64).await?;
// >> "8.0"
// >> "7.0"
// Using a more advanced value type such as a struct by implementing the serde traits
#[derive(Serialize, Deserialize, Debug)]
struct Date {
month: String,
day: String,
}
event_emitter.on(
"LOG_DATE",
|_date: Date| async move { println!("{_date:?}") },
);
event_emitter
.emit(
"LOG_DATE",
Date {
month: "January".to_string(),
day: "Tuesday".to_string(),
},
)
.await?;
event_emitter
.emit(
"LOG_DATE",
Date {
month: "February".to_string(),
day: "Tuesday".to_string(),
},
)
.await?;
// >> "Month: January - Day: Tuesday"
// >> "Month: January - Day: Tuesday"
Ok(())
}
移除监听器也很简单
use async_event_emitter::AsyncEventEmitter as EventEmitter;
let mut event_emitter = EventEmitter::new();
let listener_id = event_emitter.on("Hello", |_: ()| async { println!("Hello World") });
match event_emitter.remove_listener(&listener_id) {
Some(listener_id) => println!("Removed event listener! {listener_id}"),
None => println!("No event listener of that id exists"),
}
创建全局EventEmitter
您可能希望有一个可以在文件间共享的单个EventEmitter实例;
毕竟,使用EventEmitter的主要目的之一是避免通过多个嵌套函数/类型传递值,并有一个全局订阅服务。
// global_event_emitter.rs
use async_event_emitter::AsyncEventEmitter;
use futures::lock::Mutex;
use lazy_static::lazy_static;
// Use lazy_static! because the size of EventEmitter is not known at compile time
lazy_static! {
// Export the emitter with `pub` keyword
pub static ref EVENT_EMITTER: Mutex<AsyncEventEmitter> = Mutex::new(AsyncEventEmitter::new());
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// We need to maintain a lock through the mutex so we can avoid data races
EVENT_EMITTER
.lock()
.await
.on("Hello", |_: ()| async { println!("hello there!") });
EVENT_EMITTER.lock().await.emit("Hello", ()).await?;
Ok(())
}
async fn random_function() {
// When the <"Hello"> event is emitted in main.rs then print <"Random stuff!">
EVENT_EMITTER
.lock()
.await
.on("Hello", |_: ()| async { println!("Random stuff!") });
}
使用async-std而不是tokio
Tokio是此库的默认运行时,但可以通过禁用crate的默认功能并启用use-async-std
功能来启用async-std支持。
注意:只需将tokio::main替换为async-std::main,将tokio::test替换为async-std::test(前提是您已启用crate上的“attributes”功能)。
测试
如下运行此crate的所有功能测试: cargo test --all-features
许可
MIT许可(MIT),见LICENSE
依赖项
~4-15MB
~191K SLoC