Giter Club home page Giter Club logo

pubsubjs's Issues

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 ...

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

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

Offer minified version.

I believe that you should incorporate minified version of the library in to repository.
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.

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?

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?

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?

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

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?

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)

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');

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();
}

Publish to a CDN

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

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?

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?

PubSub instanceable

Two ways to access the PubSub component:

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

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');

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

.

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.

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);

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?

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();
}

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.

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

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.

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.

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?

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.

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.

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

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

Minor readme typo

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

Cancel specific >subscripiton<
...

Not found in Bower

Can't find it in Bower.

bower install PubSubJS
ENOTFOUND Package PubSubJS not found

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.

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.)

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.

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
});

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.

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.

Late Subscribers

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

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.

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.