Let us consider this example, use of EventEmitter:
import { EventEmitter } from"events";consteventEmitter=newEventEmitter();eventEmitter.on("text", text =>console.log(text));eventEmitter.once("time", time =>console.log(time));eventEmitter.emit("text","hi!"); //Prints "hi!"eventEmitter.emit("time",123); //Prints "123"eventEmitter.emit("time",1234); //Prints nothing ( once )
In EVT the recommended approach is to give every event it's Evt instance. Translation of the example:
import { Evt } from"evt";//Or import { Evt } from "https://evt.land/x/evt/mod.ts" on denoconstevtText=Evt.create<string>();constevtTime=Evt.create<number>();evtText.attach(text =>console.log(text));evtTime.attachOnce(time =>console.log(time));evtText.post("hi!");evtTime.post(123);evtTime.post(1234);
However, the traditional approach that consists of gathering all the events in a single bus is also an option.
Note: Due to a current TypeScript limitation the .attach()methods need to be prefixed with $ when used with fλ ( to in this case) operators but evt.$attach*() are actually just aliases to the corresponding evt.attach*() methods.
import { Evt, to } from"evt";constevt=Evt.create< [ "text", string ] | [ "time", number ]>();evt.$attach(to("text"), text =>console.log(text));evt.$attachOnce(to("time"), time =>console.log(time));evt.post(["text","hi!"]);evt.post(["time",123]);evt.post(["time",1234]);
Unlike RxJS operators that return Observable EVT operators are function build using native language features, no by composing other pre-existing operators or instantiating any particular class.
Consider that we have an emitter for this data type: