'Handle event emitter messages sequentially

myEmitter.on('data', handleData).

How can I have handleData invoked sequentially and not in parallel ?

For example: n data messages arrive grouped very closely in time together, and I want them to be handled in order sequentially, never in parallel.

Can I achieve this easily with some library ?

note: handleData is async



Solution 1:[1]

If you have an additional event like end you'd be able to store each data item in an array in the order in which they arrive. After you receive the end event you can process the previously stored data queue sequentially.

Example:

const dataQueue = [];
myEmitter.on('data', data => dataQueue.push(data));
myEmitter.on('end', () => dataQueue.forEach(handleData));

However, you won't be able to start processing before all data has arrived.

Solution 2:[2]

I've built a library for doing this that you're welcome to try out.

https://www.npmjs.com/package/event-iterable

https://github.com/cbroad/event-iterable

It will allow you to use the for-await-of statement to sequentially process your events.

const { EventIterable } = require( "event-iterable" );
async function example() {
    const it = EventIterable.wrap( myEmitter, "data" );
    /* You'll likely want to signal this loop to 
     * stop handling events by calling it.stop().
     * You could use a timer:
     *     setTimeout( () => it.stop(), 10000 );
     * or call it as a response to another event:
     *     myEmitter.once( "end", () => it.stop() );
     * or whenever you feel like it.
     */
    for await ( const handleData of it ) {
        // process your data here
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 stefanpartheym
Solution 2