Skip to content

Instantly share code, notes, and snippets.

@j-
Last active July 10, 2019 01:45
Show Gist options
  • Save j-/3c470e51d6ec59fba993acc0db0d353a to your computer and use it in GitHub Desktop.
Save j-/3c470e51d6ec59fba993acc0db0d353a to your computer and use it in GitHub Desktop.
Really simple pubsub
import { create } from './pubsub';
it('`create()` returns object with `publish` and `subscribe` fns', () => {
const result = create();
expect(result).toBeInstanceOf(Object);
expect(result).toHaveProperty('publish');
expect(result.publish).toBeInstanceOf(Function);
expect(result).toHaveProperty('subscribe');
expect(result.subscribe).toBeInstanceOf(Function);
});
it('can publish with no subscribers', () => {
const { publish } = create<number>();
expect(() => {
publish(111);
}).not.toThrow();
});
it('can publish with one subscriber', () => {
const { subscribe, publish } = create<number>();
const callback = jest.fn();
subscribe(callback);
publish(222);
expect(callback).toHaveBeenCalledWith(222);
});
it('can publish with two subscribers', () => {
const { subscribe, publish } = create<number>();
const callback1 = jest.fn();
const callback2 = jest.fn();
subscribe(callback1);
subscribe(callback2);
publish(333);
expect(callback1).toHaveBeenCalledWith(333);
expect(callback2).toHaveBeenCalledWith(333);
});
it('can unsubscribe from subscribers', () => {
const { subscribe, publish } = create<number>();
const callback1 = jest.fn();
const callback2 = jest.fn();
const unsubscribe = subscribe(callback1);
subscribe(callback2);
unsubscribe();
publish(444);
expect(callback1).not.toHaveBeenCalled();
expect(callback2).toHaveBeenCalledWith(444);
});
it('can subscribe many times', () => {
const { subscribe, publish } = create<number>();
const callback = jest.fn();
subscribe(callback);
subscribe(callback);
publish(555);
expect(callback).toHaveBeenCalledTimes(2);
expect(callback).toHaveBeenCalledWith(555);
});
it('can unsubscribe many times', () => {
const { subscribe, publish } = create<number>();
const callback1 = jest.fn();
const callback2 = jest.fn();
const unsubscribe = subscribe(callback1);
subscribe(callback2);
unsubscribe();
unsubscribe();
unsubscribe();
publish(666);
expect(callback1).not.toHaveBeenCalled();
expect(callback2).toHaveBeenCalledWith(666);
});
export type Callback<T> = (arg: T) => void;
export const create = <T>() => {
const callbacks: Callback<T>[] = [];
return {
publish (value: T) {
callbacks
.filter(Boolean)
.forEach((cb) => cb(value));
},
subscribe (callback: Callback<T>) {
const i = callbacks.push(callback) - 1;
return () => delete callbacks[i];
},
};
};
@j-
Copy link
Author

j- commented Feb 14, 2019

Creates a pubsub pair.

const { subscribe, publish } = create();
subscribe(value => console.log(`Got ${value}`));
publish(1234); // => "Got 1234"

Subscribe function returns unsubscribe function.

const { subscribe, publish } = create();
const unsubscribe = subscribe(value => console.log(`Got ${value}`));
unsubscribe();
publish(1234); // Does nothing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment