· 6 years ago · Dec 03, 2019, 09:26 PM
1// represent the following API, in other words implement the Events function/class
2
3// scaffold
4class Events {
5 constructor() {
6 this.currentTopics = {};
7 }
8 publish(topic, payload) {
9 const toPublish = this.currentTopics[topic];
10 if (toPublish) {
11 debugger;
12 toPublish.forEach(cb => {
13 cb(payload);
14 });
15 }
16 }
17 // returns {remove}
18 subscribe(topic, callback) {
19 if (this.currentTopics[topic]) {
20 this.currentTopics[topic].add(callback);
21 } else {
22 this.currentTopics[topic] = new Set([callback]);
23 }
24 return {
25 remove: () => {
26 console.log("remove");
27 this.currentTopics[topic].delete(callback);
28 }
29 };
30 }
31
32 publishAll(payload) {
33 console.log("publishall");
34 for (let key in this.currentTopics) {
35 const cbSet = this.currentTopics[key];
36 cbSet.forEach(cb => cb(payload));
37 }
38 }
39
40 subscribeOnce(topic, callback) {
41 console.log("subscr once");
42 const newCB = payload => {
43 callback(payload);
44 this.currentTopics[topic].delete(callback);
45 };
46 this.subscribe(topic, newCB);
47 }
48
49 // returns a Promise
50 async subscribeOnceAsync(topic) {
51 console.log("subcribe once async");
52 return new Promise((resolve, reject) => {
53 this.subscribeOnce(topic, resolve);
54 });
55 }
56}
57
58const events = new Events();
59
60const topicSubscription = events.subscribe("topic", function(payload) {
61 console.log(`this topic has been triggered with ${payload}`);
62});
63
64events.publish("topic", "this information");
65// result:
66// this topic has been triggered with this information
67
68const otherTopicSubscription = events.subscribe("topic", function(payload) {
69 console.log(`I have been also summoned with ${payload}`);
70});
71
72events.publish("topic", "this information now");
73// result:
74// this topic has been triggered with this information now
75// I have been also summoned with this information now
76
77topicSubscription.remove();
78
79events.publish("topic", "another call with this info");
80// result:
81// I have been also summoned with another call with this info
82
83const anotherTopicSubscription = events.subscribe("AnotherTopic", function(
84 payload
85) {
86 console.log(`new topic, new life with ${payload}`);
87});
88
89events.publish("AnotherTopic", "so much to publish!");
90// result:
91// new topic, new life with so much to publish!
92
93events.publishAll("every topic deserves to know!");
94
95// result:
96// I have been also summoned with every topic deserves to know!
97// new topic, new life with every topic deserves to know!
98
99events.subscribeOnce("topic", function(payload) {
100 console.log(`this will only execute once with ${payload}`);
101});
102
103events.publish("topic", "more stuff!");
104// result:
105// I have been also summoned with more stuff!
106// this will execute only once with more stuff!
107
108events.publish("topic", "more stuff!");
109// result:
110// I have been also summoned with more stuff!
111
112events.subscribeOnceAsync("topic").then(function(payload) {
113 console.log(`this will execute only once with ${payload}`);
114});
115
116events.publish("topic", "more stuff!");
117// result:
118// I have been also summoned with more stuff!
119// this will execute only once with more stuff!
120
121events.publish("topic", "more stuff again!");
122// result:
123// I have been also summoned with more stuff again!