/events-to-async

Treat EventEmitter-like object using Async/Await, Async Iterator.

Primary LanguageTypeScriptMIT LicenseMIT

events-to-async

Treat EventEmitter-like object using Async/Await or Async Iterator.

Similar one of Node.js events.on and event.once, but it is generic.

Features

  • events to Async Iterator
  • once event to a Promise
  • support EventEmitter-like libraries
  • LightWeight: ~1kb (gzip)

Install

Install with npm:

npm install events-to-async

Usage

once an event to Promise

import { EventEmitter } from "events";
import { on } from "events-to-async";

const events = new EventEmitter();
setTimeout(() => {
    events.emit("change", 1);
});
const event = await once((handler) => events.once("change", handler));
console.log(event); // => [1]

on events to AsyncIterator

import { EventEmitter } from "events";
import { on } from "events-to-async";

const events = new EventEmitter();
const asyncIterator = on((handler) => {
    event.on("change", handler); // Listen
    return () => {
        // This function is called on occuring error or `break;`
        event.off("change", handler); // UnListen
    }
});
setTimeout(() => {
    events.emit("change", 1);
    events.emit("change", 2);
    events.emit("change", 3);
});
for await(const event of asyncIterator) {
    console.log(event); // [1] → [2] → [3]
}
// Unreachable here

You can stop the async iterator by using break;

import { EventEmitter } from "events";
import { on } from "events-to-async";

const events = new EventEmitter();
const asyncIterator = on((handler) => {
    events.on("change", handler); // Listen
    return () => {
        // This function is called on occuring error or `break;`
        events.off("change", handler); // UnListen
    }
});
setTimeout(() => {
    events.emit("change", 1);
    events.emit("change", 2);
    events.emit("change", 3);
});
for await(const [num] of asyncIterator) {
    console.log(num); // 1 → 2 → 3
    if (num === 3) {
        break;
    }
}
console.log("4!!!"); 

AbortController supports

You can cancel events using AbortController.

once an event with cancel

import { EventEmitter } from "events";
import { on } from "events-to-async";

const events = new EventEmitter();
const abortController = new AbortController();
const event = once((handler) => {
    event.once("change", handler);
    return () => {
        event.off("change", handler);  // call it when occur error or abort
    }
}, { signal: abortController.signal });
// Abort
abortController.abort();
await event; // => throw Abort Error

on events with cancel

import { EventEmitter } from "events";
import { on } from "events-to-async";

const events = new EventEmitter();
const abortController = new AbortController();
const asyncIterator = on((handler) => {
    events.on("change", handler);
    return () => {
        events.off("change", handler);
    }
}, { signal: abortController.signal });
// Abort
abortController.abort();

TypeScript supports

on<T> and once<T> support generics that represent iterated value.

📝 on<T> and once<T> always return an array

import { EventEmitter } from "events";
import { on } from "events-to-async";

const events = new EventEmitter();
type Event = number;
const asyncIterator = on<[Event]>((handler) => {
    events.on("change", handler);
    return () => events.off("change", handler)
});
setTimeout(() => {
    events.emit("change", 1);
    events.emit("change", 2);
    events.emit("change", 3);
});
for await(const event of asyncIterator) {
    console.log(event); // [1] → [2] → [3]
}

Yet another EventEmitter supports

This library aim to support yet another events module like eventmit.

import { eventmit } from "eventmit";
import { on } from "events-to-async";

type Event = { key: string };
const events = eventmit<Event>();
const asyncIterator = on<[Event]>((handler) => {
    events.on(handler);
    return () => events.off(handler);
});
setTimeout(() => {
    events.emit({ key: "value" });
});
for await (const event of asyncIterator) {
    assert.deepStrictEqual(event, [{ key: "value" }]);
    break;
}

Changelog

See Releases page.

Running tests

Install devDependencies and Run npm test:

npm test

Contributing

Pull requests and stars are always welcome.

For bugs and feature requests, please create an issue.

  1. Fork it!
  2. Create your feature branch: git checkout -b my-new-feature
  3. Commit your changes: git commit -am 'Add some feature'
  4. Push to the branch: git push origin my-new-feature
  5. Submit a pull request :D

Author

License

MIT © azu

Related