包详细信息

nextgen-events

cronvel336.9kMIT1.5.3

The next generation of events handling for javascript! New: abstract away the network!

events, async, emit, listener

自述文件

NextGen Events

The next generation of events handling!

  • License: MIT
  • Current status: stable
  • Platform: Node.js and browsers

NextGen Events solves common trouble that one may encounter when dealing with events and listeners.

Feature highlights:

  • Standard event-handling 99% compatible with Node.js built-in events
  • .emit() supports a completion callback
  • Support for asynchronous event-handling
  • Multiple listeners can be tied to a single context
  • A context can be temporarly disabled
  • A context can be in queue mode: events for its listeners are stored, they will be resumed when the context is enabled again
  • A context can be in serialization mode: each sync/async listener run once the previous sync/async listener has fully completed
  • Interruptible event emitting: if the emitter is interruptible, a listener can stop downstream propagation, thus emitting an 'interrupt' event
  • NEW: state-events: so late listeners will never miss the ready event again!
  • NEW: handling group of emitters
  • NEW: proxy services! Abstract away your network: emit and listen to emitter on the other side of the plug!
  • NEW: .waitFor()/.waitForAll() the Promise returning variant of .once()!
  • NEW: .waitForEmit() the Promise returning variant of .emit() + completion callback

Emitting events asynchronously or registering a listener that will be triggered asynchronously because it performs non-critical tasks has some virtues: it gives some breath to the event-loop, so important I/O can be processed as soon as possible.

You will love the state-event concept: you define a state bounded to the event of the same name, and when the bounded event fire, that state is turned on. If a new listener is added for that event and the bounded state is on, the new listener is triggered immediately with the same arguments that was previously emitted. You will typically make events like ready, open, end or close, etc, state-events, so late listeners will never miss your event again!

Contexts are really useful, it handles a collection of listeners. At first glance, it looks like a sort of namespace for listeners. But it can do more than that: you can turn a context off, so every listener tied to this context will not be triggered anymore. Then turn it on and they will be available again.

You can even switch a context into queue mode: the listeners tied to it will not be triggered, but events for those listeners will be stored in the context. When the context is resumed, all retained events will trigger their listeners. This allow one to postpone some operations, while performing some other high priority tasks, but be careful: depending on your application nature, the queue may grow fast and consumes a lot of memory very quickly.

One of the top feature of this lib is the context serialization: it greatly eases the flow of the code! When differents events can fire at the same time, there are use cases when one does not want that async listeners run concurrently. The context serialization feature will ensure you that no concurrency will happen for listeners tied to it. You do not have to code fancy or complicated tests to cover all cases anymore: just let NextGen Events do it for you!

Proxy services are awesome. They abstract away the network so we can emit and listen to emitter on the other side of the plug! Both side of the channel create a Proxy, and add to it local and remote services, i.e. event emitters, and that's all. A remote service looks like a normal (i.e. local) emitter, and share the same API (with few limitations). It's totally protocol agnostic, you just define two methods for your proxy: one to read from the network and one to send to it (e.g. for Web Socket, this is a one-liner).

Install

Use npm:

npm install nextgen-events

Getting started

By the way you can create an event emitter simply by creating a new object, this way:

var NgEmitter = require( 'nextgen-events' ) ;
var emitter = new NgEmitter() ;

You can use var emitter = Object.create( NgEmitter.prototype ) as well, the object does not need the constructor.

But in real life, you would make your own objects inherit it:

var NgEmitter = require( 'nextgen-events' ) ;

function myClass()
{
    // myClass constructor code here
}

myClass.prototype = Object.create( NgEmitter.prototype ) ;
myClass.prototype.constructor = myClass ;    // restore the constructor

// define other methods for myClass...

The basis of the event emitter works like Node.js built-in events:

var NgEmitter = require( 'nextgen-events' ) ;
var emitter = new NgEmitter() ;

// Normal listener
emitter.on( 'message' , function( message ) {
    console.log( 'Message received: ' , message ) ;
} ) ;

// One time listener:
emitter.once( 'close' , function() {
    console.log( 'Connection closed!' ) ;
} ) ;

// The error listener: if it is not defined, the error event will throw an exception
emitter.on( 'error' , function( error ) {
    console.log( 'Shit happens: ' , error ) ;
} ) ;

emitter.emit( 'message' , 'Hello world!' ) ;
// ...

References

Table of Content

更新日志

v1.5.3

Fix bug with listener calling .removeAllListener() and another being a one-time listener (.once())

v1.5.2

LeanEvents: slightly faster (and more benchmarks)

v1.5.1

LeanEvents: slight improvements

v1.5.0

New: LeanEvents class, with only the most basic (observer) features + state events faster than full blown NextGenEvents, no high level reserved event (error/newListener/removeListener/etc)

v1.4.0

New: .addListener()/.on() now support a 'unique' option, only adding a listener if its ID is unique for this event

v1.3.4

Improved code/performance/memory usage of .removeListener()

v1.3.3

.emitIfListener(), fixed

v1.3.2

.emitIfListener()

v1.3.1

[optimization] .listenerCount() now longer causes init or create empty event listener array, but simply return 0

v1.3.0

New: NextGenEvents.emitIntricatedEvents() (for Spellcast specific use-case, not sure if it could be useful elsewhere) nasty context serialization bug fixed when listeners are not sync

v1.2.1

Minor internal improvements

v1.2.0

New: listener priority

v1.1.1

Unit test improved, coding style enforced, etc...

v1.1.0

Change of static method names .groupGlobalOnce() -> .groupOnceFirst() and .groupGlobalOnceAll() -> .groupOnceLast(), former names are deprecated (reason: they are ambiguous and unclear) and will be removed on the next semver major. New: .groupWaitFor*() static methods

v1.0.1

Fixed README.md: advertise the lib as stable

v1.0.0

v1!

v0.15.0

.removeAllListeners() bug fixed finally added supports for setMaxListeners() and .getMaxListeners()

v0.14.6

Unit test fixed

v0.14.5

Dependencies, moved to Tea-Time's builtin 'expect'

v0.14.4

Documentation: npm sucks... big README.md are not supported

v0.14.3

More documentation fixes

v0.14.2

Documentation improved (again)

v0.14.1

Documentation improved

v0.14.0

New: .waitFor() and .waitForAll()

v0.13.1

Fixing Internal constructor using 'from' when there are contexts

v0.13.0

Context serialization refacto (deadlock prevention)

v0.12.4

New constant

v0.12.3

a console.log() was not cleaned up

v0.12.2

Spellcast specific patch

v0.12.1

Spellcast specific patch

v0.12.0

Now the __ngev property is an instance of NextGenEvents.Internal

v0.11.3

Documentation

v0.11.2

Desynced emit fixed

v0.11.1

Desync emit callback when the emitter is not SYNC

v0.11.0

Breaking change: ES6 standard update, so node v6 is required

v0.10.2

Minor fixes (build, etc)

v0.10.1

Faster emitter creation when using the 'new' operator

v0.9.9

Dependencies

v0.9.8

Test and browser tests

v0.9.7

Fixing tests to ensure async-try-catch module compatibilities

v0.9.6

Bugfix: groupEmit() now supports the nice argument

v0.9.5

async-try-catch compatibility improvements

v0.9.4

New: NextGenEvents.groupRemoveAllListeners()

v0.9.3

New: NextGenEvents.reset(), to reset an emitter

v0.9.2

Bugfixed: missing NextGenEvents init in .hasState() and .getAllStates()

v0.9.1

Bugfix: a state-event should not be emitted if the state and its event's arguments hasn't changed.

v0.9.0

Breaking change: new methods on the prototype: .hasState() and .getAllStates() ; new static method: NextGenEvents.groupDefineStates()

v0.8.0

Breaking change: .emitOnce() (0.7.x) is removed in favor of a more generic 'state-events' approach, featuring group exclusivity: .defineStates(). Normal .emit() can be used, so better backward-compatibility with 0.6.x and below.

v0.7.0

New: emit once, for 'ready'-like event

v0.6.5

Bugfix: make __ngev property configurable

v0.6.4

New: NextGenEvents.groupGlobalOnceAll()

v0.6.3

New: NextGenEvents.share(), share the event bus on differents objects

v0.6.2

Bugfixed: completion callback should be called only once for groupEmit()

v0.6.1

New features: group emitters ; compatible change: listener ID can be anything now

v0.6.0

Proxy: message now use __type instead of type, to avoid collision

v0.5.23

Bugfixed: inside a 'newListener' listener, the .listenerCount() should report correctly

v0.5.22

Fix the doc again (formating on npmjs.org's narrow column)

v0.5.21

Fix the doc

v0.5.20

Added a sparse documentation on the Proxy Services features

v0.5.19

Proxy services features: ack/callback on emit and listen!

v0.5.18

New feature: listener in 'eventObject' mode.

v0.5.17

Proxy services: basic features ok!

v0.5.16

.once() arguments management bugfixed (rare).

v0.5.14 - v0.5.15

Async-try-catch module compatibility.

v0.5.13

Browser tests.

v0.5.12

The __ngev property is not enumerable anymore.

v0.5.11

Browser build was missing...

v0.5.10

Fixed recursive emit issue when a listener modify the current listener array in the emit loop.

v0.5.9

Documentation.

v0.5.8

Browser build.

v0.5.7

Browser support: ok!

v0.5.6

Exception message clean up.

v0.5.5

Bugfix completion handler when there is no listener for an event.

v0.5.4

Internal event object changes.

v0.5.3

.emit()'s completion callback now has the event object passed as argument #1.

v0.5.2

New method .listenerCount() to be up to date with Node.js built-in events.

v0.5.1

Documentation: spelling.

v0.5.0

Breaking change: .emit() now accepts a final (optional) completion callback argument.

v0.4.1

Documentation about compatibilities with Node.js built-in events.

v0.4.0

.emit() does not return the emitter anymore, but instead an object representing the event.

The method .setInterruptible() allow the emitter to be interruptible, i.e. when an event is emitted, a listener returning a truthy value will abort the emitting process, other emitters will not receive the event. Furthermore, an 'interrupt' event will be fired.