据我了解,EventEmitter这只是事件侦听器支持的通用接口;“实现”此接口的对象提供多种事件,客户端代码可以在这些事件上放置侦听器回调。当对象自行决定发出相应事件时,将调用这些回调。由于JS是动态类型语言,这样的接口很自然地出现,并且可以由很多东西来实现。
首先,在 NodeJS 和 Rust 中,你都不能“订阅”任务/线程:你在某个对象上放置一个侦听器回调,然后这个回调将从某个线程(甚至可能是当前线程)调用,但通常是线程订阅对象的线程和运行此回调的线程是不同的。在 NodeJS 中,有一个全局事件循环,它调用函数和外部事件侦听器,而外部事件侦听器又可以调用其他事件侦听器,因此您并不真正知道哪个线程将执行侦听器。并不是说您应该关心 - 事件循环抽象向您隐藏了显式线程。
然而,Rust 是一种合适的多线程语言。它不会在全局事件循环上运行(尽管libgreen目前还可以在类似于 Node 中的事件循环中运行 Rust 程序;它将用于任务管理和 I/O 处理,但它将libstd不久的将来会分开)。默认 Rust 运行时,libnative公开了用于创建本机抢占式调度线程和本机 I/O 的设施。这意味着哪个线程最终执行回调确实很重要,并且您应该记住,所有回调都将在拥有该对象的线程中执行,除非它专门为事件处理创建单独的线程。
侦听器的另一类问题是 Rust 是静态类型语言,在静态类型语言中编写通用事件侦听器接口比在动态类型语言中更困难,因为您需要编写足够多态的接口。您还希望利用强类型系统并使您的界面尽可能类型安全。这不是一项简单的任务。当然,可以Box<Any>在任何地方使用,但是这样的 API 使用起来并不是很愉快。
因此,目前还没有通用的事件监听器接口。也没有事件总线库。但是,您始终可以自己写一些东西。如果它不是很通用,那么编写它应该不会很困难。