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

Download history 3/week @ 2024-06-08 25/week @ 2024-06-22 1/week @ 2024-06-29 96/week @ 2024-07-06 37/week @ 2024-07-13 14/week @ 2024-07-20 22/week @ 2024-07-27 12/week @ 2024-08-03 2/week @ 2024-08-10

每月下载量55

MIT许可

23KB
132

async-event-emitter

Crates.io docs.rs CI codecov License: MIT

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