This is an advanced version of problem based on the publisher-subscriber pattern, this question was asked to me in the Coursera's frontend interview.
Implement the pub-sub pattern in JavaScript that has following methods: subscribe, subscribeOnce, and subscribeOnceAsync.
// Test cases
const events = new Events();
const newUserNewsSubscription = events.subscribe("new-user", function (payload) {
console.log(`Sending Q1 News to: ${payload}`);
});
events.publish("new-user", "Jhon");
//output: "Sending Q1 News to: Jhon"
const newUserNewsSubscription2 = events.subscribe("new-user", function (payload) {
console.log(`Sending Q2 News to: ${payload}`);
});
events.publish("new-user", "Doe");
//output: "Sending Q1 News to: Doe"
//output: "Sending Q2 News to: Doe"
newUserNewsSubscription.remove(); // Q1 news is removed
events.publish("new-user", "Foo");
//output: "Sending Q2 News to: Foo"
events.publishAll("FooBar");
//output: "Sending Q2 News to: FooBar"
events.subscribeOnce("new-user", function (payload) {
console.log(`I am invoked once ${payload}`);
});
events.publish("new-user", "Foo Once");
//output: "Sending Q2 News to: Foo Once" - normal event
//output: "I am invoked once Foo Once" - once event
events.publish("new-user", "Foo Twice");
//output: "Sending Q2 News to: Foo Twice" - normal event
// once event should not invoke for second time
events.subscribeOnceAsync("new-user").then(function (payload) {
console.log(`I am invoked once ${payload}`);
});
events.publish("new-user", "Foo Once Async");
//output: "Sending Q2 News to: Foo Once Async"
//output: "I am invoked once Foo Once Async"
We will maintain three different lists (map) to maintain the key-value pairs for:
Similarly we will have three different methods that will handle inputs for these three lists:
subscribe(name, callback): This will hold the subscription that can be invoked any number of timessubscribeOnce(name, callback): This will hold the subscription that will be invoked only once and it will then remove the subscriptionasync subscribeOnceAsync(name): This will hold the subscription that will be invoked only once, and the callback will be invoked when the promise is resolved or.Then we will have two methods to publish:
publish(name, data): This will publish the subscriber's with the provided value by checking the subscribers name in each list, i.e subscriptionList, subscribeOnceList, subscribeAsyncList.publishAll(data): This will publish all the subscribers with the given data. It is only applicable to subscriptionList as other list can be only invoked once.