ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅಸಿಂಕ್ ಇಟರೇಟರ್ ಸಹಾಯಕ 'ಸ್ಕ್ಯಾನ್' ಕುರಿತು ಆಳವಾದ ವಿಶ್ಲೇಷಣೆ, ಇದರ ಕಾರ್ಯಚಟುವಟಿಕೆ, ಉಪಯೋಗಗಳು, ಮತ್ತು ಅಸಿಂಕ್ರೋನಸ್ ಸಂಚಯನಾತ್ಮಕ ಸಂಸ್ಕರಣೆಗೆ ಇದರ ಪ್ರಯೋಜನಗಳು.
ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅಸಿಂಕ್ ಇಟರೇಟರ್ ಸಹಾಯಕ: ಸ್ಕ್ಯಾನ್ - ಅಸಿಂಕ್ ಸಂಚಯನಾತ್ಮಕ ಸಂಸ್ಕರಣೆ
ಆಧುನಿಕ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅಭಿವೃದ್ಧಿಯಲ್ಲಿ ಅಸಿಂಕ್ರೋನಸ್ ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಒಂದು ಮೂಲಾಧಾರವಾಗಿದೆ, ವಿಶೇಷವಾಗಿ ನೆಟ್ವರ್ಕ್ ವಿನಂತಿಗಳು ಅಥವಾ ಫೈಲ್ ಸಿಸ್ಟಮ್ ಸಂವಹನಗಳಂತಹ I/O-ಬೌಂಡ್ ಕಾರ್ಯಾಚರಣೆಗಳೊಂದಿಗೆ ವ್ಯವಹರಿಸುವಾಗ. ES2018 ರಲ್ಲಿ ಪರಿಚಯಿಸಲಾದ ಅಸಿಂಕ್ ಇಟರೇಟರ್ಗಳು, ಅಸಿಂಕ್ರೋನಸ್ ಡೇಟಾದ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಒಂದು ಶಕ್ತಿಯುತ ವ್ಯವಸ್ಥೆಯನ್ನು ಒದಗಿಸುತ್ತವೆ. RxJS ನಂತಹ ಲೈಬ್ರರಿಗಳಲ್ಲಿ ಹೆಚ್ಚಾಗಿ ಕಂಡುಬರುವ ಮತ್ತು ಸ್ವತಂತ್ರ ಯುಟಿಲಿಟಿಯಾಗಿ ಲಭ್ಯವಾಗುತ್ತಿರುವ `scan` ಸಹಾಯಕವು, ಈ ಅಸಿಂಕ್ರೋನಸ್ ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ಸಂಸ್ಕರಿಸಲು ಇನ್ನಷ್ಟು ಸಾಮರ್ಥ್ಯವನ್ನು ತೆರೆಯುತ್ತದೆ.
ಅಸಿಂಕ್ ಇಟರೇಟರ್ಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು
`ಸ್ಕ್ಯಾನ್` ಬಗ್ಗೆ ತಿಳಿಯುವ ಮೊದಲು, ಅಸಿಂಕ್ ಇಟರೇಟರ್ಗಳು ಯಾವುವು ಎಂದು ಪುನರಾವಲೋಕಿಸೋಣ. ಅಸಿಂಕ್ ಇಟರೇಟರ್ ಎನ್ನುವುದು ಅಸಿಂಕ್ ಇಟರೇಟರ್ ಪ್ರೋಟೋಕಾಲ್ಗೆ ಅನುಗುಣವಾಗಿರುವ ಒಂದು ಆಬ್ಜೆಕ್ಟ್. ಈ ಪ್ರೋಟೋಕಾಲ್ `next()` ಮೆಥಡ್ ಅನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ, ಅದು ಎರಡು ಪ್ರಾಪರ್ಟಿಗಳನ್ನು ಹೊಂದಿರುವ ಆಬ್ಜೆಕ್ಟ್ಗೆ ರಿಸಾಲ್ವ್ ಆಗುವ ಪ್ರಾಮಿಸ್ ಅನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ: `value` (ಸರಣಿಯಲ್ಲಿನ ಮುಂದಿನ ಮೌಲ್ಯ) ಮತ್ತು `done` (ಇಟರೇಟರ್ ಮುಗಿದಿದೆಯೇ ಎಂದು ಸೂಚಿಸುವ ಬೂಲಿಯನ್). ಕಾಲಾನಂತರದಲ್ಲಿ ಬರುವ ಡೇಟಾ ಅಥವಾ ಪಡೆಯಲು ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳ ಅಗತ್ಯವಿರುವ ಡೇಟಾದೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ ಅಸಿಂಕ್ ಇಟರೇಟರ್ಗಳು ವಿಶೇಷವಾಗಿ ಉಪಯುಕ್ತವಾಗಿವೆ.
ಇಲ್ಲಿ ಅಸಿಂಕ್ ಇಟರೇಟರ್ನ ಒಂದು ಮೂಲಭೂತ ಉದಾಹರಣೆ ಇದೆ:
async function* generateNumbers() {
yield 1;
yield 2;
yield 3;
}
async function main() {
const iterator = generateNumbers();
let result = await iterator.next();
console.log(result); // { value: 1, done: false }
result = await iterator.next();
console.log(result); // { value: 2, done: false }
result = await iterator.next();
console.log(result); // { value: 3, done: false }
result = await iterator.next();
console.log(result); // { value: undefined, done: true }
}
main();
`ಸ್ಕ್ಯಾನ್` ಸಹಾಯಕದ ಪರಿಚಯ
`ಸ್ಕ್ಯಾನ್` ಸಹಾಯಕ (ಇದನ್ನು `accumulate` ಅಥವಾ `reduce` ಎಂದೂ ಕರೆಯಲಾಗುತ್ತದೆ) ಒಂದು ಅಕ್ಯುಮ್ಯುಲೇಟರ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಪ್ರತಿ ಮೌಲ್ಯಕ್ಕೆ ಅನ್ವಯಿಸಿ ಮತ್ತು ಸಂಗ್ರಹವಾದ ಫಲಿತಾಂಶವನ್ನು ಹೊರಸೂಸುವ ಮೂಲಕ ಅಸಿಂಕ್ ಇಟರೇಟರ್ ಅನ್ನು ರೂಪಾಂತರಿಸುತ್ತದೆ. ಇದು ಅರೇಗಳ ಮೇಲಿನ `reduce` ಮೆಥಡ್ಗೆ ಹೋಲುತ್ತದೆ, ಆದರೆ ಇದು ಅಸಿಂಕ್ರೋನಸ್ ಆಗಿ ಮತ್ತು ಇಟರೇಟರ್ಗಳ ಮೇಲೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ.
ಸಾರಾಂಶದಲ್ಲಿ, `ಸ್ಕ್ಯಾನ್` ಒಂದು ಅಸಿಂಕ್ ಇಟರೇಟರ್, ಒಂದು ಅಕ್ಯುಮ್ಯುಲೇಟರ್ ಫಂಕ್ಷನ್, ಮತ್ತು ಐಚ್ಛಿಕ ಆರಂಭಿಕ ಮೌಲ್ಯವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ. ಮೂಲ ಇಟರೇಟರ್ನಿಂದ ಹೊರಸೂಸುವ ಪ್ರತಿ ಮೌಲ್ಯಕ್ಕೆ, ಅಕ್ಯುಮ್ಯುಲೇಟರ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಹಿಂದಿನ ಸಂಗ್ರಹವಾದ ಮೌಲ್ಯ (ಅಥವಾ ಮೊದಲ ಇಟರೇಷನ್ ಆಗಿದ್ದರೆ ಆರಂಭಿಕ ಮೌಲ್ಯ) ಮತ್ತು ಇಟರೇಟರ್ನಿಂದ ಪ್ರಸ್ತುತ ಮೌಲ್ಯದೊಂದಿಗೆ ಕರೆಯಲಾಗುತ್ತದೆ. ಅಕ್ಯುಮ್ಯುಲೇಟರ್ ಫಂಕ್ಷನ್ನ ಫಲಿತಾಂಶವು ಮುಂದಿನ ಸಂಗ್ರಹವಾದ ಮೌಲ್ಯವಾಗುತ್ತದೆ, ಅದನ್ನು ನಂತರ ಫಲಿತಾಂಶದ ಅಸಿಂಕ್ ಇಟರೇಟರ್ನಿಂದ ಹೊರಸೂಸಲಾಗುತ್ತದೆ.
ಸಿಂಟ್ಯಾಕ್ಸ್ ಮತ್ತು ಪ್ಯಾರಾಮೀಟರ್ಗಳು
`ಸ್ಕ್ಯಾನ್` ಬಳಸುವ ಸಾಮಾನ್ಯ ಸಿಂಟ್ಯಾಕ್ಸ್ ಈ ಕೆಳಗಿನಂತಿದೆ:
async function* scan(sourceIterator, accumulator, initialValue) {
let accumulatedValue = initialValue;
for await (const value of sourceIterator) {
accumulatedValue = accumulator(accumulatedValue, value);
yield accumulatedValue;
}
}
- `sourceIterator`: ರೂಪಾಂತರಿಸಬೇಕಾದ ಅಸಿಂಕ್ ಇಟರೇಟರ್.
- `accumulator`: ಎರಡು ಆರ್ಗ್ಯುಮೆಂಟ್ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುವ ಫಂಕ್ಷನ್: ಹಿಂದಿನ ಸಂಗ್ರಹವಾದ ಮೌಲ್ಯ ಮತ್ತು ಇಟರೇಟರ್ನಿಂದ ಪ್ರಸ್ತುತ ಮೌಲ್ಯ. ಇದು ಹೊಸ ಸಂಗ್ರಹವಾದ ಮೌಲ್ಯವನ್ನು ಹಿಂತಿರುಗಿಸಬೇಕು.
- `initialValue` (ಐಚ್ಛಿಕ): ಅಕ್ಯುಮ್ಯುಲೇಟರ್ನ ಆರಂಭಿಕ ಮೌಲ್ಯ. ಇದನ್ನು ಒದಗಿಸದಿದ್ದರೆ, ಮೂಲ ಇಟರೇಟರ್ನ ಮೊದಲ ಮೌಲ್ಯವನ್ನು ಆರಂಭಿಕ ಮೌಲ್ಯವಾಗಿ ಬಳಸಲಾಗುತ್ತದೆ ಮತ್ತು ಅಕ್ಯುಮ್ಯುಲೇಟರ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಎರಡನೇ ಮೌಲ್ಯದಿಂದ ಕರೆಯಲು ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತದೆ.
ಉಪಯೋಗದ ಸಂದರ್ಭಗಳು ಮತ್ತು ಉದಾಹರಣೆಗಳು
`ಸ್ಕ್ಯಾನ್` ಸಹಾಯಕವು ಅತ್ಯಂತ ಬಹುಮುಖವಾಗಿದೆ ಮತ್ತು ಅಸಿಂಕ್ರೋನಸ್ ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ಒಳಗೊಂಡಿರುವ ವ್ಯಾಪಕ ಶ್ರೇಣಿಯ ಸನ್ನಿವೇಶಗಳಲ್ಲಿ ಬಳಸಬಹುದು. ಇಲ್ಲಿ ಕೆಲವು ಉದಾಹರಣೆಗಳಿವೆ:
1. ಚಾಲನೆಯಲ್ಲಿರುವ ಒಟ್ಟು ಮೊತ್ತವನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡುವುದು
ನೀವು ವಹಿವಾಟಿನ ಮೊತ್ತವನ್ನು ಹೊರಸೂಸುವ ಅಸಿಂಕ್ ಇಟರೇಟರ್ ಅನ್ನು ಹೊಂದಿದ್ದೀರಿ ಎಂದು ಕಲ್ಪಿಸಿಕೊಳ್ಳಿ. ಈ ವಹಿವಾಟುಗಳ ಚಾಲನೆಯಲ್ಲಿರುವ ಒಟ್ಟು ಮೊತ್ತವನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡಲು ನೀವು `ಸ್ಕ್ಯಾನ್` ಅನ್ನು ಬಳಸಬಹುದು.
async function* generateTransactions() {
yield 10;
yield 20;
yield 30;
}
async function main() {
const transactions = generateTransactions();
const runningTotals = scan(transactions, (acc, value) => acc + value, 0);
for await (const total of runningTotals) {
console.log(total); // Output: 10, 30, 60
}
}
main();
ಈ ಉದಾಹರಣೆಯಲ್ಲಿ, `accumulator` ಫಂಕ್ಷನ್ ಪ್ರಸ್ತುತ ವಹಿವಾಟಿನ ಮೊತ್ತವನ್ನು ಹಿಂದಿನ ಒಟ್ಟು ಮೊತ್ತಕ್ಕೆ ಸೇರಿಸುತ್ತದೆ. `initialValue` 0 ಆಗಿರುವುದರಿಂದ ಚಾಲನೆಯಲ್ಲಿರುವ ಒಟ್ಟು ಮೊತ್ತ ಶೂನ್ಯದಿಂದ ಪ್ರಾರಂಭವಾಗುತ್ತದೆ.
2. ಡೇಟಾವನ್ನು ಅರೇಯಲ್ಲಿ ಸಂಗ್ರಹಿಸುವುದು
ನೀವು ಅಸಿಂಕ್ ಇಟರೇಟರ್ನಿಂದ ಡೇಟಾವನ್ನು ಅರೇಯಲ್ಲಿ ಸಂಗ್ರಹಿಸಲು `ಸ್ಕ್ಯಾನ್` ಅನ್ನು ಬಳಸಬಹುದು. ಕಾಲಾನಂತರದಲ್ಲಿ ಡೇಟಾವನ್ನು ಸಂಗ್ರಹಿಸಲು ಮತ್ತು ಅದನ್ನು ಬ್ಯಾಚ್ಗಳಲ್ಲಿ ಸಂಸ್ಕರಿಸಲು ಇದು ಉಪಯುಕ್ತವಾಗಬಹುದು.
async function* fetchData() {
yield { id: 1, name: 'Alice' };
yield { id: 2, name: 'Bob' };
yield { id: 3, name: 'Charlie' };
}
async function main() {
const dataStream = fetchData();
const accumulatedData = scan(dataStream, (acc, value) => [...acc, value], []);
for await (const data of accumulatedData) {
console.log(data); // Output: [{id: 1, name: 'Alice'}], [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}], [{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}, {id: 3, name: 'Charlie'}]
}
}
main();
ಇಲ್ಲಿ, `accumulator` ಫಂಕ್ಷನ್ ಹಿಂದಿನ ಎಲ್ಲಾ ಎಲಿಮೆಂಟ್ಗಳು ಮತ್ತು ಪ್ರಸ್ತುತ ಮೌಲ್ಯವನ್ನು ಒಳಗೊಂಡಿರುವ ಹೊಸ ಅರೇಯನ್ನು ರಚಿಸಲು ಸ್ಪ್ರೆಡ್ ಆಪರೇಟರ್ (`...`) ಅನ್ನು ಬಳಸುತ್ತದೆ. `initialValue` ಒಂದು ಖಾಲಿ ಅರೇ ಆಗಿದೆ.
3. ರೇಟ್ ಲಿಮಿಟರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು
ಒಂದು ಹೆಚ್ಚು ಸಂಕೀರ್ಣವಾದ ಬಳಕೆಯ ಪ್ರಕರಣವೆಂದರೆ ರೇಟ್ ಲಿಮಿಟರ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು. ನಿರ್ದಿಷ್ಟ ಸಮಯದ ವಿಂಡೋದಲ್ಲಿ ಮಾಡಿದ ವಿನಂತಿಗಳ ಸಂಖ್ಯೆಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡಲು ಮತ್ತು ದರ ಮಿತಿಯನ್ನು ಮೀರಿದರೆ ನಂತರದ ವಿನಂತಿಗಳನ್ನು ವಿಳಂಬಗೊಳಿಸಲು ನೀವು `ಸ್ಕ್ಯಾನ್` ಅನ್ನು ಬಳಸಬಹುದು.
async function* generateRequests() {
// Simulate incoming requests
yield Date.now();
await new Promise(resolve => setTimeout(resolve, 200));
yield Date.now();
await new Promise(resolve => setTimeout(resolve, 100));
yield Date.now();
}
async function main() {
const requests = generateRequests();
const rateLimitWindow = 1000; // 1 second
const maxRequestsPerWindow = 2;
async function* rateLimitedRequests(source, window, maxRequests) {
let queue = [];
for await (const requestTime of source) {
queue.push(requestTime);
queue = queue.filter(t => requestTime - t < window);
if (queue.length > maxRequests) {
const earliestRequest = queue[0];
const delay = window - (requestTime - earliestRequest);
console.log(`Rate limit exceeded. Delaying for ${delay}ms`);
await new Promise(resolve => setTimeout(resolve, delay));
}
yield requestTime;
}
}
const limited = rateLimitedRequests(requests, rateLimitWindow, maxRequestsPerWindow);
for await (const requestTime of limited) {
console.log(`Request processed at ${requestTime}`);
}
}
main();
ಈ ಉದಾಹರಣೆಯು ವಿನಂತಿಯ ಟೈಮ್ಸ್ಟ್ಯಾಂಪ್ಗಳ ಕ್ಯೂ ಅನ್ನು ನಿರ್ವಹಿಸಲು ಆಂತರಿಕವಾಗಿ (`rateLimitedRequests` ಫಂಕ್ಷನ್ನಲ್ಲಿ) `ಸ್ಕ್ಯಾನ್` ಅನ್ನು ಬಳಸುತ್ತದೆ. ಇದು ದರ ಮಿತಿ ವಿಂಡೋದಲ್ಲಿನ ವಿನಂತಿಗಳ ಸಂಖ್ಯೆಯು ಅನುಮತಿಸಲಾದ ಗರಿಷ್ಠ ಸಂಖ್ಯೆಯನ್ನು ಮೀರಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸುತ್ತದೆ. ಮೀರಿದರೆ, ಅದು ಅಗತ್ಯವಾದ ವಿಳಂಬವನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡುತ್ತದೆ ಮತ್ತು ವಿನಂತಿಯನ್ನು ನೀಡುವ ಮೊದಲು ವಿರಾಮಗೊಳಿಸುತ್ತದೆ.
4. ನೈಜ-ಸಮಯದ ಡೇಟಾ ಸಂಗ್ರಾಹಕವನ್ನು ನಿರ್ಮಿಸುವುದು (ಜಾಗತಿಕ ಉದಾಹರಣೆ)
ವಿವಿಧ ವಿನಿಮಯ ಕೇಂದ್ರಗಳಿಂದ ನೈಜ-ಸಮಯದ ಸ್ಟಾಕ್ ಬೆಲೆಗಳನ್ನು ಒಟ್ಟುಗೂಡಿಸಬೇಕಾದ ಜಾಗತಿಕ ಹಣಕಾಸು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಪರಿಗಣಿಸಿ. ಅಸಿಂಕ್ ಇಟರೇಟರ್ ನ್ಯೂಯಾರ್ಕ್ ಸ್ಟಾಕ್ ಎಕ್ಸ್ಚೇಂಜ್ (NYSE), ಲಂಡನ್ ಸ್ಟಾಕ್ ಎಕ್ಸ್ಚೇಂಜ್ (LSE), ಮತ್ತು ಟೋಕಿಯೊ ಸ್ಟಾಕ್ ಎಕ್ಸ್ಚೇಂಜ್ (TSE) ನಂತಹ ವಿನಿಮಯ ಕೇಂದ್ರಗಳಿಂದ ಬೆಲೆ ನವೀಕರಣಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಬಹುದು. ಎಲ್ಲಾ ವಿನಿಮಯ ಕೇಂದ್ರಗಳಲ್ಲಿ ನಿರ್ದಿಷ್ಟ ಸ್ಟಾಕ್ನ ಚಾಲನೆಯಲ್ಲಿರುವ ಸರಾಸರಿ ಅಥವಾ ಗರಿಷ್ಠ/ಕನಿಷ್ಠ ಬೆಲೆಯನ್ನು ನಿರ್ವಹಿಸಲು `ಸ್ಕ್ಯಾನ್` ಅನ್ನು ಬಳಸಬಹುದು.
// Simulate streaming stock prices from different exchanges
async function* generateStockPrices() {
yield { exchange: 'NYSE', symbol: 'AAPL', price: 170.50 };
yield { exchange: 'LSE', symbol: 'AAPL', price: 170.75 };
await new Promise(resolve => setTimeout(resolve, 50));
yield { exchange: 'TSE', symbol: 'AAPL', price: 170.60 };
}
async function main() {
const stockPrices = generateStockPrices();
// Use scan to calculate a running average price
const runningAverages = scan(
stockPrices,
(acc, priceUpdate) => {
const { total, count } = acc;
return { total: total + priceUpdate.price, count: count + 1 };
},
{ total: 0, count: 0 }
);
for await (const averageData of runningAverages) {
const averagePrice = averageData.total / averageData.count;
console.log(`Running average price: ${averagePrice.toFixed(2)}`);
}
}
main();
ಈ ಉದಾಹರಣೆಯಲ್ಲಿ, `accumulator` ಫಂಕ್ಷನ್ ಬೆಲೆಗಳ ಚಾಲನೆಯಲ್ಲಿರುವ ಒಟ್ಟು ಮೊತ್ತವನ್ನು ಮತ್ತು ಸ್ವೀಕರಿಸಿದ ನವೀಕರಣಗಳ ಸಂಖ್ಯೆಯನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡುತ್ತದೆ. ಅಂತಿಮ ಸರಾಸರಿ ಬೆಲೆಯನ್ನು ನಂತರ ಈ ಸಂಗ್ರಹವಾದ ಮೌಲ್ಯಗಳಿಂದ ಲೆಕ್ಕಹಾಕಲಾಗುತ್ತದೆ. ಇದು ವಿವಿಧ ಜಾಗತಿಕ ಮಾರುಕಟ್ಟೆಗಳಲ್ಲಿನ ಸ್ಟಾಕ್ ಬೆಲೆಯ ನೈಜ-ಸಮಯದ ನೋಟವನ್ನು ಒದಗಿಸುತ್ತದೆ.
5. ಜಾಗತಿಕವಾಗಿ ವೆಬ್ಸೈಟ್ ಟ್ರಾಫಿಕ್ ಅನ್ನು ವಿಶ್ಲೇಷಿಸುವುದು
ಪ್ರಪಂಚದಾದ್ಯಂತ ಇರುವ ಸರ್ವರ್ಗಳಿಂದ ವೆಬ್ಸೈಟ್ ಭೇಟಿ ಡೇಟಾದ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ಸ್ವೀಕರಿಸುವ ಜಾಗತಿಕ ವೆಬ್ ಅನಾಲಿಟಿಕ್ಸ್ ಪ್ಲಾಟ್ಫಾರ್ಮ್ ಅನ್ನು ಕಲ್ಪಿಸಿಕೊಳ್ಳಿ. ಪ್ರತಿ ಡೇಟಾ ಪಾಯಿಂಟ್ ವೆಬ್ಸೈಟ್ಗೆ ಭೇಟಿ ನೀಡುವ ಬಳಕೆದಾರರನ್ನು ಪ್ರತಿನಿಧಿಸುತ್ತದೆ. `ಸ್ಕ್ಯಾನ್` ಬಳಸಿ, ನಾವು ಪ್ರತಿ ದೇಶದ ಪುಟ ವೀಕ್ಷಣೆಗಳ ಪ್ರವೃತ್ತಿಯನ್ನು ನೈಜ ಸಮಯದಲ್ಲಿ ವಿಶ್ಲೇಷಿಸಬಹುದು. ಡೇಟಾ ಈ ರೀತಿ ಕಾಣುತ್ತದೆ ಎಂದು ಭಾವಿಸೋಣ: `{ country: "US", page: "homepage", timestamp: 1678886400 }`.
async function* generateWebsiteVisits() {
yield { country: 'US', page: 'homepage', timestamp: Date.now() };
yield { country: 'CA', page: 'product', timestamp: Date.now() };
yield { country: 'UK', page: 'blog', timestamp: Date.now() };
yield { country: 'US', page: 'product', timestamp: Date.now() };
}
async function main() {
const visitStream = generateWebsiteVisits();
const pageViewCounts = scan(
visitStream,
(acc, visit) => {
const { country } = visit;
const newAcc = { ...acc };
newAcc[country] = (newAcc[country] || 0) + 1;
return newAcc;
},
{}
);
for await (const counts of pageViewCounts) {
console.log('Page view counts by country:', counts);
}
}
main();
ಇಲ್ಲಿ, `accumulator` ಫಂಕ್ಷನ್ ಪ್ರತಿ ದೇಶಕ್ಕೆ ಒಂದು ಕೌಂಟರ್ ಅನ್ನು ನವೀಕರಿಸುತ್ತದೆ. ಹೊಸ ಭೇಟಿ ಡೇಟಾ ಬಂದಂತೆ, ಔಟ್ಪುಟ್ ಪ್ರತಿ ದೇಶದ ಸಂಗ್ರಹವಾಗುತ್ತಿರುವ ಪುಟ ವೀಕ್ಷಣೆಗಳ ಸಂಖ್ಯೆಯನ್ನು ತೋರಿಸುತ್ತದೆ.
`ಸ್ಕ್ಯಾನ್` ಬಳಸುವುದರ ಪ್ರಯೋಜನಗಳು
ಅಸಿಂಕ್ರೋನಸ್ ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ `ಸ್ಕ್ಯಾನ್` ಸಹಾಯಕವು ಹಲವಾರು ಪ್ರಯೋಜನಗಳನ್ನು ನೀಡುತ್ತದೆ:
- ಘೋಷಣಾತ್ಮಕ ಶೈಲಿ (Declarative Style): `ಸ್ಕ್ಯಾನ್` ನಿಮಗೆ ಸಂಚಯನಾತ್ಮಕ ಸಂಸ್ಕರಣಾ ತರ್ಕವನ್ನು ಘೋಷಣಾತ್ಮಕ ಮತ್ತು ಸಂಕ್ಷಿಪ್ತ ರೀತಿಯಲ್ಲಿ ವ್ಯಕ್ತಪಡಿಸಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ, ಇದು ಕೋಡ್ ಓದುವಿಕೆಯನ್ನು ಮತ್ತು ನಿರ್ವಹಣೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ.
- ಅಸಿಂಕ್ರೋನಸ್ ನಿರ್ವಹಣೆ: ಇದು ಅಕ್ಯುಮ್ಯುಲೇಟರ್ ಫಂಕ್ಷನ್ನೊಳಗೆ ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಸರಾಗವಾಗಿ ನಿರ್ವಹಿಸುತ್ತದೆ, ಇದು I/O-ಬೌಂಡ್ ಕಾರ್ಯಗಳನ್ನು ಒಳಗೊಂಡಿರುವ ಸಂಕೀರ್ಣ ಸನ್ನಿವೇಶಗಳಿಗೆ ಸೂಕ್ತವಾಗಿದೆ.
- ನೈಜ-ಸಮಯದ ಸಂಸ್ಕರಣೆ: `ಸ್ಕ್ಯಾನ್` ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳ ನೈಜ-ಸಮಯದ ಸಂಸ್ಕರಣೆಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ, ಬದಲಾವಣೆಗಳು ಸಂಭವಿಸಿದಂತೆ ಪ್ರತಿಕ್ರಿಯಿಸಲು ನಿಮಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ.
- ಸಂಯೋಜನೆ (Composability): ಸಂಕೀರ್ಣ ಡೇಟಾ ಸಂಸ್ಕರಣಾ ಪೈಪ್ಲೈನ್ಗಳನ್ನು ರಚಿಸಲು ಇದನ್ನು ಇತರ ಅಸಿಂಕ್ ಇಟರೇಟರ್ ಸಹಾಯಕಗಳೊಂದಿಗೆ ಸುಲಭವಾಗಿ ಸಂಯೋಜಿಸಬಹುದು.
`ಸ್ಕ್ಯಾನ್` ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು (ಲಭ್ಯವಿಲ್ಲದಿದ್ದರೆ)
ಕೆಲವು ಲೈಬ್ರರಿಗಳು ಅಂತರ್ನಿರ್ಮಿತ `ಸ್ಕ್ಯಾನ್` ಸಹಾಯಕವನ್ನು ಒದಗಿಸಿದರೂ, ಅಗತ್ಯವಿದ್ದರೆ ನೀವು ಸುಲಭವಾಗಿ ನಿಮ್ಮದೇ ಆದದನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಬಹುದು. ಇಲ್ಲಿ ಒಂದು ಸರಳ ಅನುಷ್ಠಾನವಿದೆ:
async function* scan(sourceIterator, accumulator, initialValue) {
let accumulatedValue = initialValue;
let first = true;
for await (const value of sourceIterator) {
if (first && initialValue === undefined) {
accumulatedValue = value;
first = false;
} else {
accumulatedValue = accumulator(accumulatedValue, value);
}
yield accumulatedValue;
}
}
ಈ ಅನುಷ್ಠಾನವು ಮೂಲ ಇಟರೇಟರ್ನ ಮೇಲೆ ಇಟರೇಟ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ಪ್ರತಿ ಮೌಲ್ಯಕ್ಕೆ ಅಕ್ಯುಮ್ಯುಲೇಟರ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಅನ್ವಯಿಸುತ್ತದೆ, ಸಂಗ್ರಹವಾದ ಫಲಿತಾಂಶವನ್ನು ನೀಡುತ್ತದೆ. ಇದು `initialValue` ಒದಗಿಸದಿದ್ದಾಗ, ಮೂಲ ಇಟರೇಟರ್ನ ಮೊದಲ ಮೌಲ್ಯವನ್ನು ಆರಂಭಿಕ ಮೌಲ್ಯವಾಗಿ ಬಳಸುವ ಮೂಲಕ ಆ ಪ್ರಕರಣವನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ.
`reduce` ನೊಂದಿಗೆ ಹೋಲಿಕೆ
`ಸ್ಕ್ಯಾನ್` ಅನ್ನು `reduce` ನಿಂದ ಪ್ರತ್ಯೇಕಿಸುವುದು ಮುಖ್ಯ. ಎರಡೂ ಇಟರೇಟರ್ಗಳ ಮೇಲೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತವೆ ಮತ್ತು ಅಕ್ಯುಮ್ಯುಲೇಟರ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಬಳಸುತ್ತವೆ, ಆದರೆ ಅವುಗಳ ವರ್ತನೆ ಮತ್ತು ಔಟ್ಪುಟ್ನಲ್ಲಿ ಭಿನ್ನವಾಗಿವೆ.
- `scan` ಪ್ರತಿ ಇಟರೇಷನ್ಗೆ ಸಂಗ್ರಹವಾದ ಮೌಲ್ಯವನ್ನು ಹೊರಸೂಸುತ್ತದೆ, ಸಂಚಯನದ ಚಾಲನೆಯಲ್ಲಿರುವ ಇತಿಹಾಸವನ್ನು ಒದಗಿಸುತ್ತದೆ.
- `reduce` ಇಟರೇಟರ್ನಲ್ಲಿನ ಎಲ್ಲಾ ಎಲಿಮೆಂಟ್ಗಳನ್ನು ಸಂಸ್ಕರಿಸಿದ ನಂತರ ಅಂತಿಮ ಸಂಗ್ರಹವಾದ ಮೌಲ್ಯವನ್ನು ಮಾತ್ರ ಹೊರಸೂಸುತ್ತದೆ.
ಆದ್ದರಿಂದ, ಸಂಚಯನದ ಮಧ್ಯಂತರ ಸ್ಥಿತಿಗಳನ್ನು ನೀವು ಟ್ರ್ಯಾಕ್ ಮಾಡಬೇಕಾದ ಸನ್ನಿವೇಶಗಳಿಗೆ `ಸ್ಕ್ಯಾನ್` ಸೂಕ್ತವಾಗಿದೆ, ಆದರೆ ನಿಮಗೆ ಕೇವಲ ಅಂತಿಮ ಫಲಿತಾಂಶ ಬೇಕಾದಾಗ `reduce` ಸೂಕ್ತವಾಗಿದೆ.
ದೋಷ ನಿರ್ವಹಣೆ (Error Handling)
ಅಸಿಂಕ್ರೋನಸ್ ಇಟರೇಟರ್ಗಳು ಮತ್ತು `ಸ್ಕ್ಯಾನ್` ನೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ, ದೋಷಗಳನ್ನು ಸರಿಯಾಗಿ ನಿರ್ವಹಿಸುವುದು ಅತ್ಯಗತ್ಯ. ಇಟರೇಷನ್ ಪ್ರಕ್ರಿಯೆಯಲ್ಲಿ ಅಥವಾ ಅಕ್ಯುಮ್ಯುಲೇಟರ್ ಫಂಕ್ಷನ್ನೊಳಗೆ ದೋಷಗಳು ಸಂಭವಿಸಬಹುದು. ಈ ದೋಷಗಳನ್ನು ಹಿಡಿಯಲು ಮತ್ತು ನಿರ್ವಹಿಸಲು ನೀವು `try...catch` ಬ್ಲಾಕ್ಗಳನ್ನು ಬಳಸಬಹುದು.
async function* generatePotentiallyFailingData() {
yield 1;
yield 2;
throw new Error('Something went wrong!');
yield 3;
}
async function main() {
const dataStream = generatePotentiallyFailingData();
try {
const accumulatedData = scan(dataStream, (acc, value) => acc + value, 0);
for await (const data of accumulatedData) {
console.log(data);
}
} catch (error) {
console.error('An error occurred:', error);
}
}
main();
ಈ ಉದಾಹರಣೆಯಲ್ಲಿ, `try...catch` ಬ್ಲಾಕ್ `generatePotentiallyFailingData` ಇಟರೇಟರ್ನಿಂದ ಎಸೆಯಲ್ಪಟ್ಟ ದೋಷವನ್ನು ಹಿಡಿಯುತ್ತದೆ. ನಂತರ ನೀವು ದೋಷವನ್ನು ಸೂಕ್ತವಾಗಿ ನಿರ್ವಹಿಸಬಹುದು, ಉದಾಹರಣೆಗೆ ಅದನ್ನು ಲಾಗ್ ಮಾಡುವುದು ಅಥವಾ ಕಾರ್ಯಾಚರಣೆಯನ್ನು ಮರುಪ್ರಯತ್ನಿಸುವುದು.
ತೀರ್ಮಾನ
ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅಸಿಂಕ್ ಇಟರೇಟರ್ಗಳ ಮೇಲೆ ಅಸಿಂಕ್ರೋನಸ್ ಸಂಚಯನಾತ್ಮಕ ಸಂಸ್ಕರಣೆಯನ್ನು ನಿರ್ವಹಿಸಲು `ಸ್ಕ್ಯಾನ್` ಸಹಾಯಕವು ಒಂದು ಶಕ್ತಿಯುತ ಸಾಧನವಾಗಿದೆ. ಇದು ಸಂಕೀರ್ಣ ಡೇಟಾ ರೂಪಾಂತರಗಳನ್ನು ಘೋಷಣಾತ್ಮಕ ಮತ್ತು ಸಂಕ್ಷಿಪ್ತ ರೀತಿಯಲ್ಲಿ ವ್ಯಕ್ತಪಡಿಸಲು, ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಸರಿಯಾಗಿ ನಿರ್ವಹಿಸಲು ಮತ್ತು ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ನೈಜ-ಸಮಯದಲ್ಲಿ ಸಂಸ್ಕರಿಸಲು ನಿಮಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಇದರ ಕಾರ್ಯಚಟುವಟಿಕೆ ಮತ್ತು ಬಳಕೆಯ ಸಂದರ್ಭಗಳನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವ ಮೂಲಕ, ನೀವು ಹೆಚ್ಚು ದೃಢವಾದ ಮತ್ತು ಸಮರ್ಥವಾದ ಅಸಿಂಕ್ರೋನಸ್ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು `ಸ್ಕ್ಯಾನ್` ಅನ್ನು ಬಳಸಿಕೊಳ್ಳಬಹುದು. ನೀವು ಚಾಲನೆಯಲ್ಲಿರುವ ಒಟ್ಟು ಮೊತ್ತವನ್ನು ಲೆಕ್ಕಾಚಾರ ಮಾಡುತ್ತಿರಲಿ, ಡೇಟಾವನ್ನು ಅರೇಗಳಲ್ಲಿ ಸಂಗ್ರಹಿಸುತ್ತಿರಲಿ, ರೇಟ್ ಲಿಮಿಟರ್ಗಳನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತಿರಲಿ ಅಥವಾ ನೈಜ-ಸಮಯದ ಡೇಟಾ ಸಂಗ್ರಾಹಕಗಳನ್ನು ನಿರ್ಮಿಸುತ್ತಿರಲಿ, `ಸ್ಕ್ಯಾನ್` ನಿಮ್ಮ ಕೋಡ್ ಅನ್ನು ಸರಳಗೊಳಿಸಬಹುದು ಮತ್ತು ಅದರ ಒಟ್ಟಾರೆ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಸುಧಾರಿಸಬಹುದು. ನಿಮ್ಮ ಅಸಿಂಕ್ರೋನಸ್ ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳ ಸಂಸ್ಕರಣೆಯ ಸಮಯದಲ್ಲಿ ಮಧ್ಯಂತರ ಸಂಗ್ರಹವಾದ ಮೌಲ್ಯಗಳಿಗೆ ಪ್ರವೇಶ ಬೇಕಾದಾಗ ದೋಷ ನಿರ್ವಹಣೆಯನ್ನು ಪರಿಗಣಿಸಲು ಮತ್ತು `reduce` ಬದಲಿಗೆ `ಸ್ಕ್ಯಾನ್` ಅನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಮರೆಯದಿರಿ. RxJS ನಂತಹ ಲೈಬ್ರರಿಗಳನ್ನು ಅನ್ವೇಷಿಸುವುದು ರಿಯಾಕ್ಟಿವ್ ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಮಾದರಿಗಳಲ್ಲಿ `ಸ್ಕ್ಯಾನ್` ನ ನಿಮ್ಮ ತಿಳುವಳಿಕೆ ಮತ್ತು ಪ್ರಾಯೋಗಿಕ ಅನ್ವಯವನ್ನು ಮತ್ತಷ್ಟು ಹೆಚ್ಚಿಸಬಹುದು.