Turn any event stream into an async generator. Inspired by eventChannel
from redux-saga
. Includes TypeScript typings.
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.
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!');
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);
}
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
}
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})`);
}
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!');
Please run make init
in the root directory before making any commits so the
commit-msg
hook can validate your commit messages.
eventChannel
fromredux-saga
asynciterify
(less generic than this package, more implementation-bound, no TypeScript)
deferred-async-iterator
(JavaScript with Typings available)
MIT