listenator v1.2.3
listenator
Turn any event stream into an async generator. Inspired by eventChannel
from redux-saga
. Includes TypeScript typings.
Usage
This package has one default export, listenator
, which takes a function as an
argument. That function should itself take one or two arguments, emit
and
optionally done
. listenator
returns an Asynchronous Generator which
yields anything passed to emit
. Calling done
will flush any queued events
and then complete the generator.
Note that this package is not transpiled to ES5. It targets ES2018. If you need to support older browsers or Node versions you will need to process it with Babel or TypeScript.
Examples
Simple
import listenator from 'listenator';
const numbers = listenator((emit, done) => {
emit(1);
emit(2);
emit(3);
done();
});
// In an async context this will log 1, 2, and then 3:
for await (const num of numbers) {
console.log(num);
}
// Execution picks up here because `done` was called
console.log('Hello!');
DOM Events
import listenator from 'listenator';
const clicks = listenator((emit) => {
const button = document.getElementById('my-btn');
button.addEventListener('click', emit);
});
// In an async context this will log every click event from clicking on #my-btn
for await (const click of clicks) {
console.log(num);
}
Node Events
import listenator from 'listenator';
import EventEmitter from 'events';
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
const events = listenator((emit) => {
myEmitter.on('event', () => {
console.log('an event occurred!');
});
});
myEmitter.emit('event', 'foo');
// In an async context:
for await (const event of events) {
console.log(event); // Logs 'foo', and then all future emits
}
Multiple Arguments
Just pass an array and destructure it on the way out:
import listenator from 'listenator';
const numbers = listenator((emit) => {
emit([1, 2, 3]);
});
// In an async context:
for await (const [x, y, z] of numbers) {
console.log(`(${x}, ${y}, ${z})`);
}
Deno
import listenator from 'https://deno.land/x/listenator/mod.ts';
const numbers = listenator((emit, done) => {
emit(1);
emit(2);
emit(3);
done();
});
// In an async context this will log 1, 2, and then 3:
for await (const num of numbers) {
console.log(num);
}
// Execution picks up here because `done` was called
console.log('Hello!');
Contributing
Please run make init
in the root directory before making any commits so the
commit-msg
hook can validate your commit messages.
Prior Art
eventChannel
fromredux-saga
asynciterify
(less generic than this package, more implementation-bound, no TypeScript)
Other Modules
deferred-async-iterator
(JavaScript with Typings available)
License
MIT