Asynchronous event emission with both concurrent and sequential execution patterns for triggering listeners.
Trigger events asynchronously with all listeners executing concurrently for maximum performance.
/**
* Trigger an event asynchronously with concurrent listener execution
* @param eventName - The name of the event to emit
* @param eventData - Optional data to pass to event listeners
* @returns Promise that resolves when all listeners complete or rejects if any listener throws
*/
emit<Name extends keyof EventData>(
eventName: Name,
eventData: EventData[Name]
): Promise<void>;
/**
* Trigger an event asynchronously without data
* @param eventName - The name of the event to emit
* @returns Promise that resolves when all listeners complete
*/
emit(eventName: EventName): Promise<void>;Usage Examples:
import Emittery from "emittery";
const emitter = new Emittery();
// Emit with data
await emitter.emit('user-created', {
id: '123',
name: 'Alice',
email: 'alice@example.com'
});
// Emit without data
await emitter.emit('ready');
// All listeners run concurrently
emitter.on('process-data', async (data) => {
// This listener might complete first
await fastOperation(data);
});
emitter.on('process-data', async (data) => {
// This listener runs in parallel
await slowOperation(data);
});
// Both listeners start immediately when emitted
await emitter.emit('process-data', someData);
console.log('All listeners completed');Trigger events asynchronously with listeners executing one after another in sequence.
/**
* Trigger an event asynchronously with sequential listener execution
* @param eventName - The name of the event to emit
* @param eventData - Optional data to pass to event listeners
* @returns Promise that resolves when all listeners complete sequentially, or rejects on first failure
*/
emitSerial<Name extends keyof EventData>(
eventName: Name,
eventData: EventData[Name]
): Promise<void>;
/**
* Trigger an event asynchronously without data, with sequential listener execution
* @param eventName - The name of the event to emit
* @returns Promise that resolves when all listeners complete
*/
emitSerial(eventName: EventName): Promise<void>;Usage Examples:
import Emittery from "emittery";
const emitter = new Emittery();
// Sequential processing where order matters
emitter.on('pipeline', async (data) => {
console.log('Step 1: Validating');
await validateData(data);
});
emitter.on('pipeline', async (data) => {
console.log('Step 2: Processing');
await processData(data);
});
emitter.on('pipeline', async (data) => {
console.log('Step 3: Saving');
await saveData(data);
});
// Listeners execute in the order they were registered
await emitter.emitSerial('pipeline', inputData);
console.log('Pipeline completed');
// If any step fails, remaining steps won't execute
try {
await emitter.emitSerial('critical-process', data);
} catch (error) {
console.error('Process failed at step:', error);
}Both emission methods handle errors differently:
Concurrent Emission (emit):
Sequential Emission (emitSerial):
import Emittery from "emittery";
const emitter = new Emittery();
// Concurrent error handling
emitter.on('data', async () => {
throw new Error('Listener 1 failed');
});
emitter.on('data', async () => {
console.log('Listener 2 still runs');
});
try {
await emitter.emit('data');
} catch (error) {
console.error('One listener failed:', error.message);
// Listener 2 still executed
}
// Sequential error handling
emitter.on('sequence', async () => {
throw new Error('Step 1 failed');
});
emitter.on('sequence', async () => {
console.log('This will not run');
});
try {
await emitter.emitSerial('sequence');
} catch (error) {
console.error('Sequence stopped:', error.message);
// Second listener never executed
}Emittery accepts various event name types for flexibility:
type EventName = PropertyKey; // string | symbol | numberUsage Examples:
import Emittery from "emittery";
const emitter = new Emittery();
// String event names (most common)
await emitter.emit('user-login', userData);
// Symbol event names (collision-resistant)
const INTERNAL_EVENT = Symbol('internal');
await emitter.emit(INTERNAL_EVENT, internalData);
// Number event names
await emitter.emit(404, errorData);emit() for independent listeners: When listeners don't depend on each other's completionemitSerial() for dependent operations: When listeners must complete in orderimport Emittery from "emittery";
const emitter = new Emittery();
// Good: Independent operations use concurrent emission
await emitter.emit('log-activity', activityData);
await emitter.emit('update-metrics', metricsData);
// Good: Dependent operations use sequential emission
await emitter.emitSerial('validation-chain', inputData);
// Good: Error handling
try {
await emitter.emit('risky-operation', data);
} catch (error) {
console.error('Operation failed:', error);
await emitter.emit('operation-failed', {error, data});
}