-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathobserver_stockapp.html
More file actions
146 lines (120 loc) · 4.31 KB
/
Copy pathobserver_stockapp.html
File metadata and controls
146 lines (120 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!DOCTYPE html>
<html>
<head>
<title>Stock Information App</title>
</head>
<body>
<h1>Stock Information App</h1>
<table id="stockTable">
<thead>
<tr>
<th>Summary</th>
<th>Identifier</th>
<th>Stock Price</th>
</tr>
</thead>
<tbody></tbody>
</table>
<div id="lastUpdated"></div>
<script>
// PubSub implementation
class PubSub {
constructor() {
this.topics = {};
this.subUid = -1;
}
publish(topic, args) {
if (!this.topics[topic]) {
return false;
}
const subscribers = this.topics[topic];
let len = subscribers.length;
while (len--) {
subscribers[len].func(topic, args);
}
return this;
}
subscribe(topic, func) {
if (!this.topics[topic]) {
this.topics[topic] = [];
}
const token = (++this.subUid).toString();
this.topics[topic].push({
token,
func,
});
return token;
}
unsubscribe(token) {
for (const topic in this.topics) {
if (this.topics.hasOwnProperty(topic)) {
const subscribers = this.topics[topic];
for (let i = 0; i < subscribers.length; i++) {
if (subscribers[i].token === token) {
subscribers.splice(i, 1);
return token;
}
}
}
}
return this;
}
}
const pubsub = new PubSub();
// Return the current local time to be used in our UI later
const getCurrentTime = () => {
const date = new Date();
const m = date.getMonth() + 1;
const d = date.getDate();
const y = date.getFullYear();
const t = date.toLocaleTimeString().toLowerCase();
return `${m}/${d}/${y} ${t}`;
};
// Add a new row of data to our fictional grid component
const addGridRow = (data) => {
const stockTable = document.getElementById('stockTable');
const tbody = stockTable.querySelector('tbody');
const row = document.createElement('tr');
const summaryCell = document.createElement('td');
const identifierCell = document.createElement('td');
const stockPriceCell = document.createElement('td');
summaryCell.textContent = data.summary;
identifierCell.textContent = data.identifier;
stockPriceCell.textContent = data.stockPrice.toFixed(2);
row.appendChild(summaryCell);
row.appendChild(identifierCell);
row.appendChild(stockPriceCell);
tbody.appendChild(row);
};
// Update our fictional grid to show the time it was last updated
const updateCounter = () => {
const lastUpdated = document.getElementById('lastUpdated');
lastUpdated.textContent = `Last Updated: ${getCurrentTime()}`;
};
// Update the grid using the data passed to our subscribers
const gridUpdate = (topic, data) => {
if (data !== undefined) {
addGridRow(data);
updateCounter();
}
};
// Create a subscription to the newDataAvailable topic
const subscriber = pubsub.subscribe('newDataAvailable', gridUpdate);
// Simulate publishing new stock data at regular intervals
setTimeout(() => {
pubsub.publish('newDataAvailable', {
summary: 'Apple made $5 billion',
identifier: 'APPL',
stockPrice: 570.91,
});
}, 2000);
setTimeout(() => {
pubsub.publish('newDataAvailable', {
summary: 'Microsoft made $20 million',
identifier: 'MSFT',
stockPrice: 30.85,
});
}, 4000);
</script>
</body>
</html>