M
Matt Kruse
I've written my own "pub/sub" module. Below is the API. Any thoughts?
I wrote my own because I didn't find one that I liked, and that had
all the features I wanted/needed. Some of the features in mine are:
- Subscribe to multiple events with a single function
- Subscribe to wildcards, like all "game/*" messages
- Set priority on subscribers so they fire in order
- Allow subscribers to pass data between them for the life of the
event
- Asynchronous or synchronous publishing of messages
- persistent messages that fire for new subscribers AFTER the publish
has happened
- Subscribers may cancel the bubble
- library agnostic
The code is actually fairly simple and has been working well already.
I plan to publish it soon for others to use. Here is the API. See if
it makes sense?
/*
Arbiter.js
by Matt Kruse
Arbiter.js is an implementation of the Pub/Sub (Observer) pattern. It
allows
messages to be published to a central controller (Arbiter), which then
pushes
the messages to all subscribers.
=======================================================================
PUBLISH a message
Arbiter.publish( msg [, data [, options] ] )
Returns: true on success, false if any subscriber has thrown a js
exception
=======================================================================
// Simple publish
Arbiter.publish( 'component/msg' );
// Publish with data, which will be passed to subscribers
Arbiter.publish( 'component/msg' , {"data":"value"} );
// Don't allow subscribers to cancel the message bubble
Arbiter.publish( 'component/msg' , null, {cancelable:false} );
// Make a message persistent. This message will be delivered to any
code that
// subscribes even after the publish has finished
Arbiter.publish( 'component/msg' , null, {persist:true} );
// Fire the subscribers asynchronously, so their execution doesn't
// delay the rest of your code from running
// (Note: async messages cannot be cancelled by subscribers)
Arbiter.publish( 'component/msg', null, {async:true} );
=======================================================================
SUBSCRIBE to a message
Arbiter.subscribe( msg, func )
Arbiter.subscribe( msg, options, func )
Arbiter.subscribe( msg, options, context, func )
Returns: subscription id
or [id1,id2] if subscribing to multiple messages
Subscribed Function = function( published_data, msg, subscriber_data )
{}
- "this" will be set to context, if passed in
- published_data = data published along with the message, if any
- msg = the message published
- subscriber_data = data that subscribers can set arbitrarily, which
will
be passed to subsequent subscribers
=======================================================================
// Simple subscribe
Arbiter.subscribe( 'component/msg', function() { } );
// Subscribe to multiple messages at once with the same function
// Note: The 2nd argument to the subscriber is the message string!
Arbiter.subscribe( 'component/msg, component/msg2', function() { } );
// Subscribe to all messages matching a wildcard expression
Arbiter.subscribe( 'component/*', function() { } );
// Subscribe to ALL messages (useful for logging, for example)
Arbiter.subscribe( '*', function() { } );
// Set priority so subscribers get called in proper order
// (default priority=0, positive=higher priority)
Arbiter.subscribe( 'msg', {priority:10}, func(){} );
Arbiter.subscribe( 'msg', {priority:20}, func(){} ); // Called first!
// If there are persisted messages, call for those too
// (Both publisher and subscriber must request this for it to work)
Arbiter.subscribe( 'msg', {persist:true}, func(){} );
// Set the subscriber context (this)
Arbiter.subscribe( 'msg', null, document.getElementById('x'),
function() {
x.innerHTML = "Message handled!";
}
);
=======================================================================
UNSUBSCRIBE / RESUBSCRIBE to a message
Arbiter.unsubscribe( subscription_id )
Returns: true if unsubscribe successful, else false
Arbiter.resubscribe( subscription_id )
Returns: true if resubscribe successful, else false
=======================================================================
var subscription_id = Arbiter.subscribe( 'msg', function(){} );
Arbiter.unsubscribe( subscription_id );
Arbiter.resubscribe( subscription_id );
*/
I wrote my own because I didn't find one that I liked, and that had
all the features I wanted/needed. Some of the features in mine are:
- Subscribe to multiple events with a single function
- Subscribe to wildcards, like all "game/*" messages
- Set priority on subscribers so they fire in order
- Allow subscribers to pass data between them for the life of the
event
- Asynchronous or synchronous publishing of messages
- persistent messages that fire for new subscribers AFTER the publish
has happened
- Subscribers may cancel the bubble
- library agnostic
The code is actually fairly simple and has been working well already.
I plan to publish it soon for others to use. Here is the API. See if
it makes sense?
/*
Arbiter.js
by Matt Kruse
Arbiter.js is an implementation of the Pub/Sub (Observer) pattern. It
allows
messages to be published to a central controller (Arbiter), which then
pushes
the messages to all subscribers.
=======================================================================
PUBLISH a message
Arbiter.publish( msg [, data [, options] ] )
Returns: true on success, false if any subscriber has thrown a js
exception
=======================================================================
// Simple publish
Arbiter.publish( 'component/msg' );
// Publish with data, which will be passed to subscribers
Arbiter.publish( 'component/msg' , {"data":"value"} );
// Don't allow subscribers to cancel the message bubble
Arbiter.publish( 'component/msg' , null, {cancelable:false} );
// Make a message persistent. This message will be delivered to any
code that
// subscribes even after the publish has finished
Arbiter.publish( 'component/msg' , null, {persist:true} );
// Fire the subscribers asynchronously, so their execution doesn't
// delay the rest of your code from running
// (Note: async messages cannot be cancelled by subscribers)
Arbiter.publish( 'component/msg', null, {async:true} );
=======================================================================
SUBSCRIBE to a message
Arbiter.subscribe( msg, func )
Arbiter.subscribe( msg, options, func )
Arbiter.subscribe( msg, options, context, func )
Returns: subscription id
or [id1,id2] if subscribing to multiple messages
Subscribed Function = function( published_data, msg, subscriber_data )
{}
- "this" will be set to context, if passed in
- published_data = data published along with the message, if any
- msg = the message published
- subscriber_data = data that subscribers can set arbitrarily, which
will
be passed to subsequent subscribers
=======================================================================
// Simple subscribe
Arbiter.subscribe( 'component/msg', function() { } );
// Subscribe to multiple messages at once with the same function
// Note: The 2nd argument to the subscriber is the message string!
Arbiter.subscribe( 'component/msg, component/msg2', function() { } );
// Subscribe to all messages matching a wildcard expression
Arbiter.subscribe( 'component/*', function() { } );
// Subscribe to ALL messages (useful for logging, for example)
Arbiter.subscribe( '*', function() { } );
// Set priority so subscribers get called in proper order
// (default priority=0, positive=higher priority)
Arbiter.subscribe( 'msg', {priority:10}, func(){} );
Arbiter.subscribe( 'msg', {priority:20}, func(){} ); // Called first!
// If there are persisted messages, call for those too
// (Both publisher and subscriber must request this for it to work)
Arbiter.subscribe( 'msg', {persist:true}, func(){} );
// Set the subscriber context (this)
Arbiter.subscribe( 'msg', null, document.getElementById('x'),
function() {
x.innerHTML = "Message handled!";
}
);
=======================================================================
UNSUBSCRIBE / RESUBSCRIBE to a message
Arbiter.unsubscribe( subscription_id )
Returns: true if unsubscribe successful, else false
Arbiter.resubscribe( subscription_id )
Returns: true if resubscribe successful, else false
=======================================================================
var subscription_id = Arbiter.subscribe( 'msg', function(){} );
Arbiter.unsubscribe( subscription_id );
Arbiter.resubscribe( subscription_id );
*/