Coder Social home page Coder Social logo

pubsubjs's Introduction

PubSubJS

NPM versionMIT LicenseNPM downloads/monthCoverage Status

PubSubJS is a topic-based publish/subscribe library written in JavaScript.

PubSubJS has synchronisation decoupling, so topics are published asynchronously. This helps keep your program predictable as the originator of topics will not be blocked while consumers process them.

For the adventurous, PubSubJS also supports synchronous topic publication. This can give a speedup in some environments (browsers, not all), but can also lead to some very difficult to reason about programs, where one topic triggers publication of another topic in the same execution chain.

Single process

PubSubJS is designed to be used within a single process, and is not a good candidate for multi-process applications (like Node.js – Cluster with many sub-processes). If your Node.js app is a single process app, you're good. If it is (or is going to be) a multi-process app, you're probably better off using redis Pub/Sub or similar

Key features

  • Dependency free
  • synchronisation decoupling
  • ES3 compatible. PubSubJS should be able to run everywhere that can execute JavaScript. Browsers, servers, ebook readers, old phones, game consoles.
  • AMD / CommonJS module support
  • No modification of subscribers (jQuery custom events modify subscribers)
  • Easy to understand and use (thanks to synchronisation decoupling)
  • Small(ish), less than 1kb minified and gzipped

Getting PubSubJS

There are several ways of getting PubSubJS

Note: the last version of this library available via bower is v1.5.4

Examples

First you have to import the module:

import PubSub from 'pubsub-js'

// or when using CommonJS
const PubSub = require('pubsub-js');

Basic example

// create a function to subscribe to topics
var mySubscriber = function (msg, data) {
    console.log( msg, data );
};

// add the function to the list of subscribers for a particular topic
// we're keeping the returned token, in order to be able to unsubscribe
// from the topic later on
var token = PubSub.subscribe('MY TOPIC', mySubscriber);

// publish a topic asynchronously
PubSub.publish('MY TOPIC', 'hello world!');

// publish a topic synchronously, which is faster in some environments,
// but will get confusing when one topic triggers new topics in the
// same execution chain
// USE WITH CAUTION, HERE BE DRAGONS!!!
PubSub.publishSync('MY TOPIC', 'hello world!');

Cancel specific subscription

// create a function to receive the topic
var mySubscriber = function (msg, data) {
    console.log(msg, data);
};

// add the function to the list of subscribers to a particular topic
// we're keeping the returned token, in order to be able to unsubscribe
// from the topic later on
var token = PubSub.subscribe('MY TOPIC', mySubscriber);

// unsubscribe this subscriber from this topic
PubSub.unsubscribe(token);

Cancel all subscriptions for a function

// create a function to receive the topic
var mySubscriber = function(msg, data) {
    console.log(msg, data);
};

// unsubscribe mySubscriber from ALL topics
PubSub.unsubscribe(mySubscriber);

Clear all subscriptions for a topic

PubSub.subscribe('a', myFunc1);
PubSub.subscribe('a.b', myFunc2);
PubSub.subscribe('a.b.c', myFunc3);

PubSub.unsubscribe('a.b');
// no further notifications for 'a.b' and 'a.b.c' topics
// notifications for 'a' will still get published

Clear all subscriptions

PubSub.clearAllSubscriptions();
// all subscriptions are removed

Get Subscriptions

PubSub.getSubscriptions('token');
// subscriptions by token from all topics

Count Subscriptions

PubSub.countSubscriptions('token');
// count by token from all topics

Error Handling

// isPublished is a boolean that represents if any subscribers was registered for this topic
var isPublished = PubSub.publish('a');

// token will be false if something went wrong and subscriber was not registered
var token = PubSub.subscribe('MY TOPIC', mySubscriber); 

Hierarchical addressing

// create a subscriber to receive all topics from a hierarchy of topics
var myToplevelSubscriber = function (msg, data) {
    console.log('top level: ', msg, data);
}

// subscribe to all topics in the 'car' hierarchy
PubSub.subscribe('car', myToplevelSubscriber);

// create a subscriber to receive only leaf topic from hierarchy op topics
var mySpecificSubscriber = function (msg, data) {
    console.log('specific: ', msg, data);
}

// subscribe only to 'car.drive' topics
PubSub.subscribe('car.drive', mySpecificSubscriber);

// Publish some topics
PubSub.publish('car.purchase', {name: 'my new car'});
PubSub.publish('car.drive', {speed: '14'});
PubSub.publish('car.sell', {newOwner: 'someone else'});

// In this scenario, myToplevelSubscriber will be called for all
// topics, three times in total
// But, mySpecificSubscriber will only be called once, as it only
// subscribes to the 'car.drive' topic

Tips

Use "constants" for topics and not string literals. PubSubJS uses strings as topics, and will happily try to deliver your topics with ANY topic. So, save yourself from frustrating debugging by letting the JavaScript engine complain when you make typos.

Example of use of "constants"

// πŸ‘Ž Bad usage
PubSub.subscribe('hello', function (msg, data) {
	console.log(data)
});

PubSub.publish('hello', 'world');

// πŸ‘ Better usage
var MY_TOPIC = 'hello';
PubSub.subscribe(MY_TOPIC, function (msg, data) {
	console.log(data)
});

PubSub.publish(MY_TOPIC, 'world');

Example of use of "symbol constants" with ES6/7 syntax

// event-types.js
export const MY_TOPIC = Symbol('MY_TOPIC')

// somefile.js
import { MY_TOPIC } from './event-types.js'
PubSub.subscribe(MY_TOPIC, function (msg, data) {
	console.log(data)
});

PubSub.publish(MY_TOPIC, 'world');

Immediate Exceptions for stack traces in developer tools

As of version 1.3.2, you can force immediate exceptions (instead of delayed exceptions), which has the benefit of maintaining the stack trace when viewed in dev tools.

This should be considered a development only option, as PubSubJS was designed to try to deliver your topics to all subscribers, even when some fail.

Setting immediate exceptions in development is easy, just tell PubSubJS about it after it has been loaded.

PubSub.immediateExceptions = true;

Contributing to PubSubJS

Please see CONTRIBUTING.md

More about Publish/Subscribe

Versioning

PubSubJS uses Semantic Versioning for predictable versioning.

Changelog

Please see https://github.com/mroderick/PubSubJS/releases

License

MIT: http://mrgnrdrck.mit-license.org

Alternatives

These are a few alternative projects that also implement topic based publish subscribe in JavaScript.

pubsubjs's People

Contributors

abishek-srinivasan avatar amclin avatar amilajack avatar an-bo avatar aron avatar contolini avatar dependabot-preview[bot] avatar dependabot[bot] avatar dlebedynskyi avatar favna avatar fernandogmar avatar firatoltulu avatar ghost23 avatar jimaek avatar joscha avatar joseph-tohdjojo avatar kelp404 avatar krasu avatar lorenzos avatar m4x1m1l14n avatar maheshsenni avatar mateuszgachowski avatar michsch avatar mroderick avatar olleolleolle avatar rubennorte avatar ryuurock avatar shaneporter avatar shibukawa avatar ssokurenko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pubsubjs's Issues

Why window.PubSub is not the same object returned by require('pubsub-js')?

Any reason why:

var PubSub = require('pubsub-js');
PubSub === window.PubSub; // false

I see in the first line of the source file that factory() is called twice, one for AMD/CommonJS (lines 12 and 16) and one for the browser (line 23). That way the two objects are not the same, and so you cannot use require('pubsub-js') and window.PubSub interchangeably.

Isn't possible to make it so, creating a single unique singleton object accross AMD/CommonJS and browser?

Potential Memory leak and a potential fix

I have came across a potential memory leak in this scenario:
Frameset page that hosts PubSub
Frame 1 loads page 1, and connects to the PubSub on the frameset
window.PubSub = top.PubSub;
Frame 2 loads page 2 and connects to PubSub on the frameset
window.PubSub = top.PubSub;
the frames can now send messages to one another without any problem

now Frame 1 loads page 3 that connects to the PubSub on the frameset but without page 1 unsubscribing first.
Now when frame 2 tries to send a message to frame 1 there are actually two listeners in the delivery: 1 and 3. When delivery is attempted to 1 weird things happen:
on FF it passes without any exception but nothing actually happens
on IE an exception is thrown -2146823277 β€œCan't execute code from a freed script”. When inspecting the code the function pointer is still there with all code so actually the DOM is still held for the page. the reason for this error according to some posts online is that the window hosting the script has been closed/removed (which is correct as the frame contents has been replaced)

obviously if a lot of pages subscribe but never unsubscribe before being replaced there will be a big memory leak. My suggestion for a fix (which will work on IE at least) is to catch the specific exception -2146823277 when trying to invoke the subscriber and if caught remove the subscriber from the list of subscribers.
I am not sure how the same could be done on FF/Chrome as they do not throw an exception and I have not found a way to check if the window is still alive (except maybe when subscribing provide the window object the function is on and then check if that object is still alive or not)

Pass the msg as the second argument

I would recommend to pass msg as a second argument. Because you are supposed to use data first. And that becomes very annoying to rewrite APIs to skip the msg argument and to see the editor's highlighting of unused local variable.

So, instead of:

var mySubscriber = function( msg, data ){ // do something with data };

do this:

var mySubscriber = function( data ){ // do something with data };

Isn't it better?

Improve developer tools and documentation

The developer documentation could use some improvements

  • Document all needed requirements (like node, grunt, npm, phantomjs)
  • Remove the need for grunt globals, npm should be enough?

Support for configuring channel / topic delimiter

Hi, what about adding an option to choose a different channel / topic delimiter, say "/" instead of the standard "."?

Could be done like this: PubSub.configure({delimiter: "/"});

Shouldn't be too hard, so if you like I can make a pull request.

Speed up when events spawn events

There's a simple way to increase the throughput of asynchronous events when they spawn each other.

The idea is to only have the first call to publish() call setTimeout, which creates an event pump for all the events that the first event spawned. These subsequent events get added to a queue, which the event pump drains. When the event queue is empty, the pump exits (returns in javascript), and the next event spawns a new event pump.

I've coded it up:

jsperf (unpublished): http://jsperf.com/pubsubjs-vs-jquery-custom-events/17

code: https://gist.github.com/1715452

(I also cleaned up the code a bit, but didn't have access to all the tests, which is why I didn't do this as a pull request.)

suggestion for return value if published via publishSync

When using publishSync wouldn't it be better to return as a return value the return value of the subscribed functions chained, instead of the way it is now, where the return value indicates if there are subscribers? . i.e. call all subscribers in a hierarchical order and if the returned value of a subscriber function is true continue with the next subscriber if it is false return false to publishSync. What do you think? Or should we implement a second "publishChainedSync" (or some other better name) ....
Ognian

Offer ready built versions

It would be extremely nice if there would be ready built versions for people who don't have things like rake installed, nor have no use for it. Normal & jQuery version.

Allow unsubscribe with message, or message + token/function

Perhaps this is related to (or duplicate of) #32.

It would be great to have an option to unsubscribe all handlers for a given message. This is actually the most common practice in most pubsub implementations, e.g:

subscribe('message', handler); // subscribe handler to 'message'
subscribe('message', anotherHandler); // another handler is subscribed
unsubscribe('message'); // stop all form listening to 'message' event

Moreover, it would be great to be able to use this in conjunction with existing API, to be able to unsubscribe a specific handler from a given message, so that a handler could be used for multiple messages, but easily removed from listening to a single message, without the need for a token.

The need to be able to not use the token is mostly for interoperability, since it's not so common API for other pubsub libraries.

Thanks!
~Y

Try-Catch block

The try-catch block on line 82 makes it very difficult to determine where errors have occurred as the error stack shows PubSub as the source of the exception.

try {
    subscribers[i].func( message, data );
} catch( e ){
    setTimeout( throwException(e), 0);
}

Is there a reason why this is in place? Otherwise I would remove it to provide better debugging data to those developing.

Thanks,
Alistair

Broken link in readme

The link "A Comparison of JS Publish/Subscribe Approaches" is broken. I would be interested in seeing that comparison, if it still exists ...

CDN delivers old version

CDN provides pubsub.js but it is not the latest version.

//cdn.jsdelivr.net/pubsubjs/1.4.2/pubsub.js

In addition to that, if README has URL of CDN, it will be more excellent.

Is scoping the callback function possible?

The problem I'm having is that I want to call a method on a class, and that method references variables with in the class. Currently they are out of scope and return undefined.

This is the basic idea $.pubsub("subscribe", "update_stuff", callbackFunc, scopeOfCallBackFunc)
Is it currently possible to do something like this? Any recommendations?

Allow to clear all subscribers for a topic by changing uid to a number

I wanted to do PubSub.unsubscribe('topic') but can't. Instead to unsubscribe an event I either have to maintain the returned ids or I have to maintain a reference to the handler function.

If the unique id returned by subscribe were to just be var token = ++lastUid, you could overload the unsubscribe method by checking for a number to do the same as strings do right now. Then you could use the string case to drop all handlers for a certain topic.

The only impact I see right now is to users who rely on the subscribe return value being a string. I'm not sure why anyone would though since for them it's just a token.

The fixes are trivial but I don't know whether you're open to such a change.

Enhancement: sticky events support

It would be nice to support sticky events concept: the idea is that some events will "stick" in PubSub and if any subscriber subscribes for such events after them was published, the subscribers will still receive them upon registration.

Consider for example this use case: there is a system-wise event, broadcasting when the user was logged in. There are many components, which are interested in receiving this event. But not all off them were already loaded at the moment when log in took place.

Problem use in requirejs

It's weired that when i run rake jquery to get a jquery pubsub version.After that, i use it in requriejs version 2.1.8+ where the config is like

requirejs.config({
        'paths': {
            'jquery': 'jquery-1.10.2.min',
            'pubsub': 'jquery.pubsub'
        },
        'shim': {
            'pubsub': ['jquery']
        }
});

it produced a error said

PubSub is not defined` in line `pubsub.version = PubSub.name + ' ' + PubSub.version;

It seem that the the line 38
``
if (typeof exports === 'object' && module){
module.exports = factory();

// AMD
} else if (typeof define === 'function' && define.amd){
    define(factory);
// Browser
} else {
    root.PubSub = factory();
}

Using PubSubJS with Sockets

Would like to know how can I use it with socket implementation.
I'm building a notification/messaging service (not-node.js based), and wanted a lightweight pubsub architecture that can connect to the socket and do the pub-sub calling.

Have you tried it?

Before I write the before function

Hey there,

I'm considering writing a project specific extension to you package, but before I did, I thought I'd throw the idea your way to see if you'd want to include such a feature.

In a specific scenario, I require to pause the publication of an event while something else happens. I was considering writing a "before" function. It might look something like:

before('someMessage', (message, data, done) => {
  // Once "someMessage" is published, none of the subscribers will
  // be notified until I call `done()`
  doSomethingAsynchronous().then(done);
});

No worries if this is not suitable for your package, but if it is, it would save forking.

Ta.

reThrowing exceptions kills the stack

When an exception occurs in a subscribe handler pubsubjs catches it and rethrows it after a timeout to ensure that the message has been passed to all subscribers:
https://github.com/mroderick/PubSubJS/blob/master/src/pubsub.js#L40-L52

This behavior of throwing the exception at a later point seems to kill the exception stack, making it a lot harder to debug exceptions, for example when you have your dev tools set to pause on uncaught exceptions.

Possible solutions:

  • Don't try/catch at all (changes behavior)
  • Set a dev flag that disables try/catch for debugging
  • Some magic fairy dust that keeps the current behavior but also keeps the stack alive. Have no idea if this is possible

Not found in Bower

Can't find it in Bower.

bower install PubSubJS
ENOTFOUND Package PubSubJS not found

Support for "delayed notifying"

It would be nice if I had an option that allows me to subscribe to a certain event and still get a notification, even if I subscribed to a message only after it already has been published.

Minor readme typo

Thanks for an excellent library. There's a minor typo in your readme:
...

Cancel specific >subscripiton<
...

Unsubscribe inside publish triggers an error

Hi

Firstly thanks for this great piece of asynchronous code!

Sometimes there is a need to unsubscribe from a message in a callback. At the moment (in some conditions) it triggers an error. Code example:

var mySubscriber = function(msg, data) {
  PubSub.unsubscribe(mySubscriber);
  console.log('mySubscriber');
};
var mySubscriber2 = function(msg, data) {
  console.log('mySubscriber2');
};

PubSub.subscribe( 'MY MESSAGE', mySubscriber);
PubSub.subscribe( 'MY MESSAGE', mySubscriber2);

PubSub.publish( 'MY MESSAGE', 'hello world!' );

BR

PubSub.subscribe - check validity of func?

Would it be possible to add a check to in the subscribe function that func is actually a function. Currently if func is undefined or not a function the error only occurs when the message is published

PubSub.subscribe = function( message, func )

Or do you think this is necessary/unlikely that is it not worth checking?

Many thanks

.

support for wildcards, e.g: level1.*.level3

How would you feel for support for wildcards?, e.g:

given:

a.b.d.e
a.b.d.f
a.c.d

a.*.d would subscribe to all 3.

There' s a couple of cases I'm looking at at where having wildcards would solve the usecase of otherwise needing 2 hierarchies to describe the events.

Would this be useful?

Namespaces don't work correctly

You have to create a subscriber on each of the namespaces from root to the penultimate topic; otherwise it fails on a logical error.

variable found at line 92 is set to true on a parent topic, but the moment that a topic that's closer to root doesn't have a subscribe the found turns to false and that's what is eventually bubbled up. It previously found a matching subscriber and never delivered the message.

This works:
var rootTopic = 'a.b.c';

pubsub.subscribe(rootTopic, function (ev) {
    console.log("this happened -> ", ev);
});
pubsub.subscribe('a.b.c', function (ev) {
    console.log('this happened --> ', ev);
});
pubsub.subscribe('a.b', function (ev) {
    console.log('this happened --> ', ev);
});
pubsub.subscribe('a', function (ev) {
    console.log('this happened --> ', ev);
});
pubsub.publish(rootTopic + '.closed');

This doesn’t work:
var rootTopic = 'a.b.c';

pubsub.subscribe(rootTopic, function (ev) {
    console.log("this happened -> ", ev);
});
pubsub.publish(rootTopic + '.closed');

publish() Always Returns True After Subscribers Have Been Removed

The publish() and publishSync() methods return a boolean. I assume (and I could be wrong as I did not see it documented) this boolean value indicates whether or not there were any subscribers to the topic.

It seems that the publish() [and publishSync()] method returns true if there was ever a subscriber to the topic, regardless of whether such a subscriber currently exists.

Here is an example. After the subscriber removes itself, the publish() method will always still return true.

// Example Code:
function documentReady() {
var unsubscribeToken = PubSub.subscribe('AAA', function (msg, data) {
console.log("Received a published message to the 'AAA' topic...");

    // Unsubscribe. There should be no more subscribers, but publish()
    // still returns true, forever.
    PubSub.unsubscribe(unsubscribeToken);
});

$("#theButton").click(function () {
    var pubResult = PubSub.publish('AAA', null);

    // IT SEEMS pubResult IS ALWAYS true!!
    console.log("After publish, pubResult=" + pubResult);
});

}

jQuery(document).ready(documentReady);

Publish to a CDN

It would be awesome to have this on code.jquery.com or some such.

Call unsubscribe inside a subscribed function jumps the next calling subscription.

The issue can be reproduced as follow:

            A = PubSub.subscribe('test', function () { PubSub.unsubscribe(A); console.log('A'); });
            B = PubSub.subscribe('test', function () { console.log('B'); });
            C = PubSub.subscribe('test', function () { console.log('C'); });

            PubSub.publish('test');

Output:
A
C

The problem is here:

    for (i = 0; i < subscribers.length; i++) {
        callSubscriber(subscribers[i].func, originalMessage, data);
    }

subscribers array should be cloned before calling susbscribers.

Feature request: set the context when registering a callback

Radio allows you specify the context for a registered callback, and sets 'this' when executing it. This would be very useful for PubSubJS as well.

Something like

Foo.prototype.init = function() {
this.token = PubSub.subscribe( 'MY TOPIC', this.myCallback, this );
};

Foo.prototype.myCallback = function(msg, data) {
// 'this' should be the Foo instance, but is instead the window object
}

var foo = Foo();
PubSub.publish('MY TOPIC', 'hello world');

PubSub instanceable

Two ways to access the PubSub component:

  • Singleton (already exist)
  • multiple instances like
    var event2 = new PubSub();
    
    

Problem with loading Karma test runner

The following code works fine in the browser with AMD but doesn't work in Karma test runner:

define(['pubsub'], function (pubsub) {
  pubsub.publish('test');
});

In Karma, pubsub is undefined, because it takes the route of common js thinking that module is defined

// CommonJS
if (typeof exports === 'object' && typeof module !== 'undefined'){
    module.exports = factory();

// AMD
} else if (typeof define === 'function' && define.amd){
    define(factory);
// Browser
} else {
    root.PubSub = factory();
}

PubSub is not defined

There seems to be a problem in your jquery version.

I get a "PubSub is not defined" when including it in my project. It seems you dont expose PubSub to the jquery wrapper.

Late Subscribers

Is it possible to have late subscribers? Where a subscriber gets notified even if he subscribes later then the message fires

Offer minified version.

I believe that you should incorporate minified version of the library in to repository.
Thanks.

Still maintained?

This seems to be one of the most popular Node pub-sub repos but I see all open PR's are over half a year old and the latest release was almost 1.5 years ago.

Is this being deprecated or are there plans to maintain the package?

Collect subscribers at actual emit time rather than publish-call time

https://gist.github.com/qfox/f33a51dc7189d98efe23

Basically, this test:

PubSub.publish('foo', 'bar');
PubSub.subscribe('foo', function(name, value) {});

Currently the callback is not being fired. However, in this case they are both (which is fine).

PubSub.subscribe('foo', function(name, value) {});
PubSub.publish('foo', 'bar');
PubSub.subscribe('foo', function(name, value) {});

Due to the async nature of pubsub I expect it to evaluate target handlers at emitting time, not at call time.

This basically also means this:

var foo = PubSub.subscribe('foo', function(name, value) { throw 'No dont call me!'; });
PubSub.publish('foo', 'bar');
PubSub.unsubscribe(foo);

I expect the subscriber NOT to be called because it was removed before actually emitting the event.

NPM Publish

Just wondering about having this published to npm. Had a look there and it looks like the pubsubjs name is taken...any chance of publishing though?

Callback arguments order

I'm every day confusing that first arg is message and second is data.
I propose set obj param something like code below

subscriber( {
message:message,
data: data
});

Avoid both tab and whitespaces for code indent

It should be better not to use both tab and whitespaces for code indent.
One reason is tab will be explain to 8 character width in some environment (ex: github)
And cause the code looks very bad for reading.

messageHasSubscribers returns true when subscriptions have been canceled

Hi,

been using PubSubJS for three months now and been loving it.

But I'm now in a bit of trouble because my code depends on an undocumented feature. I noticed that PubSub.publish() returns false if there are no subscribers for a channel so I created a bit of logic like so....

if(!PubSub.publish(DO_SOMETHING, {paramA:1, paramB:2})){
     // publish will return false if there are no subscribers (I hope)
    PubSub.publish(DO_SOMETHING_ELSE, {paramA:1, paramB:2});
}

On initial page load, this works fine. When app tries to publish to DO_SOMETHING and there's no subscriber DO_SOMETHING_ELSE is called which loads loads a module with code, templates, etc. and creates a subscription for DO_SOMETHING. When that module is unloaded the subscription is canceled, but PubSub.publish(DO_SOMETHING, {}) still returns true. This means that DO_SOMETHING_ELSE is never called after that, even if there's no subscription to respond to DO_SOMETHING.

Reviewing the code, it appears that the false positive is due to messageHasSubscribers() checking for the existence of a topic but not for one or more delivery functions. Would adding that functionality cause any trouble for other users of the PubSubJS?

Thanks

Conflict with QUnit over modules global

Hi All,

I just ran into an issue where the "modules" global declared by QUnit (which apparently complies with CommonJS) causes PubSub to think a module loading framework is present and take itself out of the global namespace, causing some of my stuff to break.

See this discussion on the QUnit site:

qunitjs/qunit#190

I notice that KnockoutJS uses the following logic for detecting a module loader:

function(factory) {
// Support three module loading scenarios
if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
// [1] CommonJS/Node.js
var target = module['exports'] || exports; // module.exports is for Node.js
factory(target);
} else if (typeof define === 'function' && define['amd']) {
// [2] AMD anonymous module
define(['exports'], factory);
} else {
// [3] No module loader (plain <script> tag) - put directly in global namespace
factory(window['ko'] = {});
}
}

Could someone modify the detection code in PubSub accordingly? Much appreciated (I'll have to do this locally in the meantime).

Cheers, Andrew.

What is the advantage over use of other versions ?

I'm considering this lib vs Subtopic which is one of the many ports of Peter Higgins's script. It's more lightweight and looks like it does support the same features, while only lacking AMD support.

What would be the advantage to use this implementation instead ?

Also, it seems pubsub.js lacks the possibility to pass a scope object along with the published event. is there a particular reason to omit this feature ?

And last, any reason to use a dot as separator instead of slash ?

Thanks

.publishSync() to return the return of subscribers

Would it be in the spirit of PubSub to add the ability to capture the return value of subscribers when doing synchronous publishes? Like so:

PubSub.subscribe('event', function(data) {
    return 1;
});

PubSub.subscribe('event', function(data) {
    return 2;
});

PubSub.subscribe('event', function(data) {
    return 3;
});

PubSub.subscribe('event.something', function(data) {
    return 4;
});

var results = PubSub.publishSync('event.something', { data: 1 })

> results
> [1, 2, 3, 4]

This does have some use cases, such as in a plugin/hook architecture. A way of doing this currently would be for each subscriber to touch a global variable, which doesn't seem all that nice.

I would suggest

        if ( sync === true ){
            deliver();

to change to:

        if ( sync === true ){
            return deliver();

and then each callSubscriber inside of deliverMessage to append to a list and return that, then subsequently deliverMessage to concatenate the lists. Returning an object may be better, with the keys denoting the message name. Eg:

> results
> {
    event: [1, 2, 3],
    event.something: [4],
}

The signature of .publishSync() would change slightly, but code doing a truthy/falsy check on its current return value (true/false) should still continue to work.

Thoughts?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.