Skip to content

Commit

Permalink
Add refractionLevel
Browse files Browse the repository at this point in the history
  • Loading branch information
mbasso committed Jul 18, 2016
1 parent 4200063 commit ceff499
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 4 deletions.
2 changes: 2 additions & 0 deletions docs/api/Subscribe.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ Subscribe the given object to events.

```js
// subscribe to 'newChatPartecipant' channel
// set priority to 90 (default 100)
const subscriber = {
refractionLevel: 90,
newChatPartecipant: (payload) => {
const { username } = payload;
alert(`Hi ${username}!`);
Expand Down
28 changes: 27 additions & 1 deletion docs/basics/Subscribing.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,33 @@ unsubscribeFunction();

If you delete a subscriber making it null, Refraction will unsubscribe it for you during next publishing.

When we declare a subscriber is important to keep in mind that events will be published in a synchronous way, Refraction will notify that an event is fired after that the previous subscriber has finished his execution. For this reason subscriber might have small functions and might be a little number. However if you have a lot of subscriber on a single channel, or if you want to do some stuff asynchronously, you can put a setTimeout with 0 offset, for example, in your handler. This will execute your code asynchronously and Refraction will step over, having better performance. Here is a little example:
When we declare a subscriber is important to keep in mind that events will be published in a synchronous way, Refraction will notify that an event is fired after that the previous subscriber has finished his execution. For this reason, you can set a level to each subscriber, to determine the order of execution. A lower level indicates that the subscriber have to be executed earlier, so, an higher level indicates that the subscriber have to be executed later. Level can be specified with a prop `refractionLevel` in the subscriber, that, by default is 100. Here is an example:

```js
let i = 0;
const secondSubscriber = {
// by default refractionLevel: 100,
foo: () => {
// i = 1
i += 1;
// i = 2
}
};
const firstSubscriber = {
refractionLevel: 90,
foo: () => {
// i = 0
i += 1;
// i = 1
}
};
// subscribing order will be ignored, refractionLevel is evaluated instead
refractionInstance.subscribe(secondSubscriber);
refractionInstance.subscribe(firstSubscriber);
refractionInstance.publish('foo');
```

Consider also that subscribers might have small functions and might be a little number. However if you have a lot of subscriber on a single channel, or if you want to do some stuff asynchronously, you can put a setTimeout with 0 offset, for example, in your handler. This will execute your code asynchronously and Refraction will step over, having better performance. Here is a little example:

```js
const subscriber = {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "refraction",
"version": "1.1.0",
"version": "1.2.0",
"description": "A guard that represent central point of control in your application.",
"main": "lib/index.js",
"jsnext:main": "es/index.js",
Expand Down
3 changes: 2 additions & 1 deletion src/Mediator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ export default class Mediator {

subscribers = [];

subscribe(subscriber) {
subscribe(subscriber, compareFunction) {
if (this.subscribers.indexOf(subscriber) === -1) {
this.subscribers.push(subscriber);
this.subscribers.sort(compareFunction);
}
}

Expand Down
16 changes: 15 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import Mediator from './Mediator';
import History from './History';

const getSubscriberLevel = (subscriber) => subscriber.refractionLevel || 100;

const compareFunction = (a, b) => {
let result = 0;
const aPriority = getSubscriberLevel(a);
const bPriority = getSubscriberLevel(b);
if (aPriority < bPriority) {
result = -1;
} else if (aPriority > bPriority) {
result = 1;
}
return result;
};

export default class Refraction {

middlewares = [];
Expand Down Expand Up @@ -30,7 +44,7 @@ export default class Refraction {
}

subscribe(subscriber) {
this.mediator.subscribe(subscriber);
this.mediator.subscribe(subscriber, compareFunction);
return this.unsubscribe.bind(this, subscriber);
}

Expand Down
28 changes: 28 additions & 0 deletions test/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,34 @@ describe('Refraction', () => {
expect(refraction.mediator.subscribers).toEqual([]);
});

it('should subscribe with level', (done) => {
let i = 0;
const foo = {
refractionLevel: 90,
onTest: () => {
expect(i).toEqual(0);
i++;
},
};
const bar = {
onTest: () => {
expect(i).toEqual(1);
i++;
},
};
const lorem = {
refractionLevel: 110,
onTest: () => {
expect(i).toEqual(2);
done();
},
};
refraction.subscribe(lorem);
refraction.subscribe(foo);
refraction.subscribe(bar);
refraction.publish('onTest');
});

it('should unsubscribe', () => {
const unknownSubscriber = { onFail: () => false };
refraction.subscribe(subscriber);
Expand Down

0 comments on commit ceff499

Please sign in to comment.