ಹೊಸ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ Iterator.prototype.buffer ಸಹಾಯಕವನ್ನು ಅನ್ವೇಷಿಸಿ. ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ಸಮರ್ಥವಾಗಿ ಪ್ರೊಸೆಸ್ ಮಾಡಲು, ಅಸಿಂಕ್ರೊನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಮತ್ತು ಆಧುನಿಕ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗಾಗಿ ಸ್ವಚ್ಛ ಕೋಡ್ ಬರೆಯಲು ಕಲಿಯಿರಿ.
ಸ್ಟ್ರೀಮ್ ಪ್ರೊಸೆಸಿಂಗ್ನಲ್ಲಿ ಪಾಂಡಿತ್ಯ: ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ Iterator.prototype.buffer ಸಹಾಯಕದ ಆಳವಾದ ಅಧ್ಯಯನ
ಆಧುನಿಕ ಸಾಫ್ಟ್ವೇರ್ ಅಭಿವೃದ್ಧಿಯ ನಿರಂತರವಾಗಿ ವಿಕಸಿಸುತ್ತಿರುವ ಕ್ಷೇತ್ರದಲ್ಲಿ, ಡೇಟಾದ ನಿರಂತರ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ನಿರ್ವಹಿಸುವುದು ಇನ್ನು ಮುಂದೆ ಒಂದು ಸಣ್ಣ ಅವಶ್ಯಕತೆಯಲ್ಲ—ಅದು ಒಂದು ಮೂಲಭೂತ ಸವಾಲಾಗಿದೆ. ರಿಯಲ್-ಟೈಮ್ ಅನಾಲಿಟಿಕ್ಸ್ ಮತ್ತು WebSocket ಸಂವಹನಗಳಿಂದ ಹಿಡಿದು ದೊಡ್ಡ ಫೈಲ್ಗಳನ್ನು ಪ್ರೊಸೆಸ್ ಮಾಡುವುದು ಮತ್ತು APIಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸುವವರೆಗೆ, ಡೆವಲಪರ್ಗಳು ಒಂದೇ ಬಾರಿಗೆ ಬರದ ಡೇಟಾವನ್ನು ನಿರ್ವಹಿಸುವ ಕಾರ್ಯವನ್ನು ಹೆಚ್ಚಾಗಿ ಎದುರಿಸುತ್ತಾರೆ. ವೆಬ್ನ ಸಾರ್ವತ್ರಿಕ ಭಾಷೆಯಾದ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್, ಇದಕ್ಕಾಗಿ ಪ್ರಬಲ ಸಾಧನಗಳನ್ನು ಹೊಂದಿದೆ: ಇಟರೇಟರ್ಗಳು ಮತ್ತು ಅಸಿಂಕ್ ಇಟರೇಟರ್ಗಳು. ಆದಾಗ್ಯೂ, ಈ ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವುದು ಸಾಮಾನ್ಯವಾಗಿ ಸಂಕೀರ್ಣ, ಇಂಪರೇಟಿವ್ ಕೋಡ್ಗೆ ಕಾರಣವಾಗಬಹುದು. ಇಲ್ಲಿದೆ Iterator Helpers ಪ್ರಸ್ತಾಪ.
ಈ TC39 ಪ್ರಸ್ತಾಪವು, ಪ್ರಸ್ತುತ ಹಂತ 3 ರಲ್ಲಿದೆ (ಇದು ಭವಿಷ್ಯದ ECMAScript ಮಾನದಂಡದ ಭಾಗವಾಗಲಿದೆ ಎಂಬುದಕ್ಕೆ ಪ್ರಬಲ ಸೂಚಕ), ಇಟರೇಟರ್ ಪ್ರೊಟೊಟೈಪ್ಗಳ ಮೇಲೆ ನೇರವಾಗಿ ಉಪಯುಕ್ತತೆಯ ವಿಧಾನಗಳ ಒಂದು ಸ್ಯೂಟ್ ಅನ್ನು ಪರಿಚಯಿಸುತ್ತದೆ. ಈ ಸಹಾಯಕಗಳು .map() ಮತ್ತು .filter() ನಂತಹ ಅರೇ ವಿಧಾನಗಳ ಡಿಕ್ಲರೇಟಿವ್, ಚೈನ್ ಮಾಡಬಹುದಾದ ಸೊಬಗನ್ನು ಇಟರೇಟರ್ಗಳ ಜಗತ್ತಿಗೆ ತರುವ ಭರವಸೆ ನೀಡುತ್ತವೆ. ಈ ಹೊಸ ಸೇರ್ಪಡೆಗಳಲ್ಲಿ ಅತ್ಯಂತ ಶಕ್ತಿಶಾಲಿ ಮತ್ತು ಪ್ರಾಯೋಗಿಕವಾದದ್ದು Iterator.prototype.buffer().
ಈ ಸಮಗ್ರ ಮಾರ್ಗದರ್ಶಿ buffer ಸಹಾಯಕವನ್ನು ಆಳವಾಗಿ ಅನ್ವೇಷಿಸುತ್ತದೆ. ಅದು ಪರಿಹರಿಸುವ ಸಮಸ್ಯೆಗಳನ್ನು, ಅದು ಹೇಗೆ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಸಿಂಕ್ರೊನಸ್ ಮತ್ತು ಅಸಿಂಕ್ರೊನಸ್ ಎರಡೂ ಸಂದರ್ಭಗಳಲ್ಲಿ ಅದರ ಪ್ರಾಯೋಗಿಕ ಅನ್ವಯಗಳನ್ನು ನಾವು ಬಹಿರಂಗಪಡಿಸುತ್ತೇವೆ. ಕೊನೆಯಲ್ಲಿ, ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವ ಯಾವುದೇ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಡೆವಲಪರ್ಗೆ buffer ಏಕೆ ಅನಿವಾರ್ಯ ಸಾಧನವಾಗಲಿದೆ ಎಂಬುದನ್ನು ನೀವು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವಿರಿ.
ಮೂಲ ಸಮಸ್ಯೆ: ನಿಭಾಯಿಸಲಾಗದ ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳು
ನೀವು ಒಂದೊಂದಾಗಿ ಐಟಂಗಳನ್ನು ನೀಡುವ ಡೇಟಾ ಮೂಲದೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುತ್ತಿದ್ದೀರಿ ಎಂದು ಕಲ್ಪಿಸಿಕೊಳ್ಳಿ. ಇದು ಯಾವುದಾದರೂ ಆಗಿರಬಹುದು:
- ಒಂದು ದೊಡ್ಡ ಮಲ್ಟಿ-ಗಿಗಾಬೈಟ್ ಲಾಗ್ ಫೈಲ್ ಅನ್ನು ಲೈನ್-ಬೈ-ಲೈನ್ ಓದುವುದು.
- ನೆಟ್ವರ್ಕ್ ಸಾಕೆಟ್ನಿಂದ ಡೇಟಾ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸುವುದು.
- RabbitMQ ಅಥವಾ Kafka ನಂತಹ ಮೆಸೇಜ್ ಕ್ಯೂನಿಂದ ಈವೆಂಟ್ಗಳನ್ನು ಬಳಸುವುದು.
- ವೆಬ್ ಪುಟದಲ್ಲಿ ಬಳಕೆದಾರರ ಕ್ರಿಯೆಗಳ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಪ್ರೊಸೆಸ್ ಮಾಡುವುದು.
ಅನೇಕ ಸನ್ನಿವೇಶಗಳಲ್ಲಿ, ಈ ಐಟಂಗಳನ್ನು ಪ್ರತ್ಯೇಕವಾಗಿ ಪ್ರೊಸೆಸ್ ಮಾಡುವುದು ಅಸಮರ್ಥವಾಗಿರುತ್ತದೆ. ನೀವು ಡೇಟಾಬೇಸ್ಗೆ ಲಾಗ್ ನಮೂದುಗಳನ್ನು ಸೇರಿಸಬೇಕಾದ ಕಾರ್ಯವನ್ನು ಪರಿಗಣಿಸಿ. ಪ್ರತಿಯೊಂದು ಲಾಗ್ ಲೈನ್ಗೆ ಪ್ರತ್ಯೇಕ ಡೇಟಾಬೇಸ್ ಕಾಲ್ ಮಾಡುವುದು ನೆಟ್ವರ್ಕ್ ಲೇಟೆನ್ಸಿ ಮತ್ತು ಡೇಟಾಬೇಸ್ ಓವರ್ಹೆಡ್ನಿಂದಾಗಿ ನಂಬಲಾಗದಷ್ಟು ನಿಧಾನವಾಗಿರುತ್ತದೆ. ಈ ನಮೂದುಗಳನ್ನು ಗುಂಪು ಮಾಡುವುದು, ಅಥವಾ ಬ್ಯಾಚ್ ಮಾಡುವುದು ಮತ್ತು ಪ್ರತಿ 100 ಅಥವಾ 1000 ಲೈನ್ಗಳಿಗೆ ಒಂದೇ ಬಲ್ಕ್ ಇನ್ಸರ್ಟ್ ಮಾಡುವುದು ಹೆಚ್ಚು ಸಮರ್ಥವಾಗಿರುತ್ತದೆ.
ಸಾಂಪ್ರದಾಯಿಕವಾಗಿ, ಈ ಬಫರಿಂಗ್ ಲಾಜಿಕ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಮ್ಯಾನುಯಲ್, ಸ್ಟೇಟ್ಫುಲ್ ಕೋಡ್ ಅಗತ್ಯವಿತ್ತು. ನೀವು ಸಾಮಾನ್ಯವಾಗಿ for...of ಲೂಪ್, ತಾತ್ಕಾಲಿಕ ಬಫರ್ ಆಗಿ ಕಾರ್ಯನಿರ್ವಹಿಸಲು ಒಂದು ಅರೇ, ಮತ್ತು ಬಫರ್ ಅಪೇಕ್ಷಿತ ಗಾತ್ರವನ್ನು ತಲುಪಿದೆಯೇ ಎಂದು ಪರಿಶೀಲಿಸಲು ಕಂಡಿಷನಲ್ ಲಾಜಿಕ್ ಅನ್ನು ಬಳಸಬೇಕಿತ್ತು. ಅದು ಈ ರೀತಿ ಕಾಣಿಸಬಹುದು:
"ಹಳೆಯ ವಿಧಾನ": ಮ್ಯಾನುಯಲ್ ಬಫರಿಂಗ್
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ನೊಂದಿಗೆ ಡೇಟಾ ಮೂಲವನ್ನು ಸಿಮ್ಯುಲೇಟ್ ಮಾಡೋಣ ಮತ್ತು ನಂತರ ಫಲಿತಾಂಶಗಳನ್ನು ಮ್ಯಾನುಯಲ್ ಆಗಿ ಬಫರ್ ಮಾಡೋಣ:
// Simulates a data source yielding numbers
function* createNumberStream() {
for (let i = 1; i <= 23; i++) {
console.log(`Source yielding: ${i}`);
yield i;
}
}
function processDataInBatches(iterator, batchSize) {
let buffer = [];
for (const item of iterator) {
buffer.push(item);
if (buffer.length === batchSize) {
console.log("Processing batch:", buffer);
buffer = []; // Reset the buffer
}
}
// Don't forget to process the remaining items!
if (buffer.length > 0) {
console.log("Processing final smaller batch:", buffer);
}
}
const numberStream = createNumberStream();
processDataInBatches(numberStream, 5);
ಈ ಕೋಡ್ ಕೆಲಸ ಮಾಡುತ್ತದೆ, ಆದರೆ ಇದರಲ್ಲಿ ಹಲವಾರು ನ್ಯೂನತೆಗಳಿವೆ:
- ವಿವರಣೆ: ಬಫರ್ ಅರೇ ಮತ್ತು ಅದರ ಸ್ಥಿತಿಯನ್ನು ನಿರ್ವಹಿಸಲು ಗಮನಾರ್ಹ ಬಾಯ್ಲರ್ಪ್ಲೇಟ್ ಕೋಡ್ ಅಗತ್ಯವಿದೆ.
- ದೋಷ-ಸಾಧ್ಯತೆ: ಬಫರ್ನಲ್ಲಿ ಉಳಿದಿರುವ ಐಟಂಗಳಿಗಾಗಿ ಅಂತಿಮ ಪರಿಶೀಲನೆಯನ್ನು ಮರೆಯುವುದು ಸುಲಭ, ಇದು ಡೇಟಾ ನಷ್ಟಕ್ಕೆ ಕಾರಣವಾಗಬಹುದು.
- ಸಂಯೋಜನೆಯ ಕೊರತೆ: ಈ ಲಾಜಿಕ್ ಒಂದು ನಿರ್ದಿಷ್ಟ ಫಂಕ್ಷನ್ನೊಳಗೆ ಸೀಮಿತವಾಗಿದೆ. ನೀವು ಬ್ಯಾಚ್ಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡುವಂತಹ ಮತ್ತೊಂದು ಕಾರ್ಯಾಚರಣೆಯನ್ನು ಚೈನ್ ಮಾಡಲು ಬಯಸಿದರೆ, ನೀವು ಲಾಜಿಕ್ ಅನ್ನು ಮತ್ತಷ್ಟು ಸಂಕೀರ್ಣಗೊಳಿಸಬೇಕಾಗುತ್ತದೆ ಅಥವಾ ಅದನ್ನು ಮತ್ತೊಂದು ಫಂಕ್ಷನ್ನಲ್ಲಿ ಸುತ್ತಬೇಕಾಗುತ್ತದೆ.
- ಅಸಿಂಕ್ ಜೊತೆ ಸಂಕೀರ್ಣತೆ: ಅಸಿಂಕ್ರೊನಸ್ ಇಟರೇಟರ್ಗಳೊಂದಿಗೆ (
for await...of) ವ್ಯವಹರಿಸುವಾಗ ಲಾಜಿಕ್ ಇನ್ನಷ್ಟು ಜಟಿಲವಾಗುತ್ತದೆ, Promises ಮತ್ತು ಅಸಿಂಕ್ ಕಂಟ್ರೋಲ್ ಫ್ಲೋನ ಎಚ್ಚರಿಕೆಯ ನಿರ್ವಹಣೆ ಅಗತ್ಯವಿರುತ್ತದೆ.
ಇದೇ ರೀತಿಯ ಇಂಪರೇಟಿವ್, ಸ್ಟೇಟ್-ಮ್ಯಾನೇಜ್ಮೆಂಟ್ ತಲೆನೋವನ್ನು Iterator.prototype.buffer() ನಿವಾರಿಸಲು ವಿನ್ಯಾಸಗೊಳಿಸಲಾಗಿದೆ.
Iterator.prototype.buffer() ಪರಿಚಯ
buffer() ಸಹಾಯಕವು ಯಾವುದೇ ಇಟರೇಟರ್ ಮೇಲೆ ನೇರವಾಗಿ ಕರೆಯಬಹುದಾದ ಒಂದು ವಿಧಾನವಾಗಿದೆ. ಇದು ಒಂದೇ ಐಟಂಗಳನ್ನು ನೀಡುವ ಇಟರೇಟರ್ ಅನ್ನು ಆ ಐಟಂಗಳ ಅರೇಗಳನ್ನು (ಬಫರ್ಗಳನ್ನು) ನೀಡುವ ಹೊಸ ಇಟರೇಟರ್ ಆಗಿ ಪರಿವರ್ತಿಸುತ್ತದೆ.
ಸಿಂಟ್ಯಾಕ್ಸ್
iterator.buffer(size)
iterator: ನೀವು ಬಫರ್ ಮಾಡಲು ಬಯಸುವ ಮೂಲ ಇಟರೇಟರ್.size: ಪ್ರತಿ ಬಫರ್ನಲ್ಲಿ ಅಪೇಕ್ಷಿತ ಐಟಂಗಳ ಸಂಖ್ಯೆಯನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸುವ ಧನಾತ್ಮಕ ಪೂರ್ಣಾಂಕ.- ಹಿಂತಿರುಗಿಸುತ್ತದೆ: ಒಂದು ಹೊಸ ಇಟರೇಟರ್, ಅದು ಅರೇಗಳನ್ನು ನೀಡುತ್ತದೆ, ಅಲ್ಲಿ ಪ್ರತಿ ಅರೇ ಮೂಲ ಇಟರೇಟರ್ನಿಂದ
sizeಐಟಂಗಳವರೆಗೆ ಹೊಂದಿರುತ್ತದೆ.
"ಹೊಸ ವಿಧಾನ": ಡಿಕ್ಲರೇಟಿವ್ ಮತ್ತು ಸ್ವಚ್ಛ
ನಮ್ಮ ಹಿಂದಿನ ಉದಾಹರಣೆಯನ್ನು ಉದ್ದೇಶಿತ buffer() ಸಹಾಯಕವನ್ನು ಬಳಸಿ ರಿಫ್ಯಾಕ್ಟರ್ ಮಾಡೋಣ. ಗಮನಿಸಿ, ಇದನ್ನು ಇಂದು ಚಲಾಯಿಸಲು, ನಿಮಗೆ ಪಾಲಿಫಿಲ್ ಬೇಕಾಗುತ್ತದೆ ಅಥವಾ ಪ್ರಸ್ತಾಪವನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿದ ಪರಿಸರದಲ್ಲಿರಬೇಕು.
// Polyfill or future native implementation assumed
function* createNumberStream() {
for (let i = 1; i <= 23; i++) {
console.log(`Source yielding: ${i}`);
yield i;
}
}
const numberStream = createNumberStream();
const bufferedStream = numberStream.buffer(5);
for (const batch of bufferedStream) {
console.log("Processing batch:", batch);
}
ಔಟ್ಪುಟ್ ಹೀಗಿರುತ್ತದೆ:
Source yielding: 1 Source yielding: 2 Source yielding: 3 Source yielding: 4 Source yielding: 5 Processing batch: [ 1, 2, 3, 4, 5 ] Source yielding: 6 Source yielding: 7 Source yielding: 8 Source yielding: 9 Source yielding: 10 Processing batch: [ 6, 7, 8, 9, 10 ] Source yielding: 11 Source yielding: 12 Source yielding: 13 Source yielding: 14 Source yielding: 15 Processing batch: [ 11, 12, 13, 14, 15 ] Source yielding: 16 Source yielding: 17 Source yielding: 18 Source yielding: 19 Source yielding: 20 Processing batch: [ 16, 17, 18, 19, 20 ] Source yielding: 21 Source yielding: 22 Source yielding: 23 Processing batch: [ 21, 22, 23 ]
ಈ ಕೋಡ್ ಒಂದು ದೊಡ್ಡ ಸುಧಾರಣೆಯಾಗಿದೆ. ಇದು:
- ಸಂಕ್ಷಿಪ್ತ ಮತ್ತು ಡಿಕ್ಲರೇಟಿವ್: ಉದ್ದೇಶ ತಕ್ಷಣವೇ ಸ್ಪಷ್ಟವಾಗುತ್ತದೆ. ನಾವು ಸ್ಟ್ರೀಮ್ ಅನ್ನು ತೆಗೆದುಕೊಂಡು ಅದನ್ನು ಬಫರ್ ಮಾಡುತ್ತಿದ್ದೇವೆ.
- ಕಡಿಮೆ ದೋಷ-ಸಾಧ್ಯತೆ: ಸಹಾಯಕವು ಅಂತಿಮ, ಭಾಗಶಃ ತುಂಬಿದ ಬಫರ್ ಅನ್ನು ಪಾರದರ್ಶಕವಾಗಿ ನಿರ್ವಹಿಸುತ್ತದೆ. ಆ ಲಾಜಿಕ್ ಅನ್ನು ನೀವೇ ಬರೆಯಬೇಕಾಗಿಲ್ಲ.
- ಸಂಯೋಜಿಸಬಹುದಾದದ್ದು:
buffer()ಹೊಸ ಇಟರೇಟರ್ ಅನ್ನು ಹಿಂತಿರುಗಿಸುವುದರಿಂದ, ಇದನ್ನುmapಅಥವಾfilterನಂತಹ ಇತರ ಇಟರೇಟರ್ ಸಹಾಯಕಗಳೊಂದಿಗೆ ಸರಾಗವಾಗಿ ಚೈನ್ ಮಾಡಬಹುದು. ಉದಾಹರಣೆಗೆ:numberStream.filter(n => n % 2 === 0).buffer(5). - ಲೇಜಿ ಇವ್ಯಾಲ್ಯುಯೇಷನ್: ಇದು ಒಂದು ನಿರ್ಣಾಯಕ ಕಾರ್ಯಕ್ಷಮತೆಯ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ. ಔಟ್ಪುಟ್ನಲ್ಲಿ ಗಮನಿಸಿ, ಮುಂದಿನ ಬಫರ್ ಅನ್ನು ತುಂಬಲು ಅಗತ್ಯವಿದ್ದಾಗ ಮಾತ್ರ ಮೂಲವು ಐಟಂಗಳನ್ನು ನೀಡುತ್ತದೆ. ಇದು ಸಂಪೂರ್ಣ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಮೊದಲು ಮೆಮೊರಿಗೆ ಓದುವುದಿಲ್ಲ. ಇದು ಅತಿ ದೊಡ್ಡ ಅಥವಾ ಅನಂತ ಡೇಟಾ ಸೆಟ್ಗಳಿಗೆ ನಂಬಲಾಗದಷ್ಟು ಸಮರ್ಥವಾಗಿಸುತ್ತದೆ.
ಆಳವಾದ ಅಧ್ಯಯನ: buffer() ಜೊತೆ ಅಸಿಂಕ್ರೊನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳು
buffer() ನ ನಿಜವಾದ ಶಕ್ತಿಯು ಅಸಿಂಕ್ರೊನಸ್ ಇಟರೇಟರ್ಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ ಹೊಳೆಯುತ್ತದೆ. ಅಸಿಂಕ್ರೊನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳು ಆಧುನಿಕ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ನ ಅಡಿಪಾಯ, ವಿಶೇಷವಾಗಿ Node.js ನಂತಹ ಪರಿಸರದಲ್ಲಿ ಅಥವಾ ಬ್ರೌಸರ್ API ಗಳೊಂದಿಗೆ ವ್ಯವಹರಿಸುವಾಗ.
ಒಂದು ಹೆಚ್ಚು ವಾಸ್ತವಿಕ ಸನ್ನಿವೇಶವನ್ನು ರೂಪಿಸೋಣ: ಪೇಜಿನೇಟೆಡ್ API ನಿಂದ ಡೇಟಾವನ್ನು ಪಡೆಯುವುದು. ಪ್ರತಿಯೊಂದು API ಕಾಲ್ ಒಂದು ಅಸಿಂಕ್ರೊನಸ್ ಕಾರ್ಯಾಚರಣೆಯಾಗಿದ್ದು, ಅದು ಫಲಿತಾಂಶಗಳ ಒಂದು ಪುಟವನ್ನು (ಒಂದು ಅರೇ) ಹಿಂತಿರುಗಿಸುತ್ತದೆ. ನಾವು ಪ್ರತಿಯೊಂದು ಫಲಿತಾಂಶವನ್ನು ಒಂದೊಂದಾಗಿ ನೀಡುವ ಅಸಿಂಕ್ ಇಟರೇಟರ್ ಅನ್ನು ರಚಿಸಬಹುದು.
// Simulate a slow API call
async function fetchPage(pageNumber) {
console.log(`Fetching page ${pageNumber}...`);
await new Promise(resolve => setTimeout(resolve, 500)); // Simulate network delay
if (pageNumber > 3) {
return []; // No more data
}
// Return 10 items for this page
return Array.from({ length: 10 }, (_, i) => `Item ${(pageNumber - 1) * 10 + i + 1}`);
}
// Async generator to yield individual items from the paginated API
async function* createApiItemStream() {
let page = 1;
while (true) {
const items = await fetchPage(page);
if (items.length === 0) {
break; // End of stream
}
for (const item of items) {
yield item;
}
page++;
}
}
// Main function to consume the stream
async function main() {
const apiStream = createApiItemStream();
// Now, buffer the individual items into batches of 7 for processing
const bufferedStream = apiStream.buffer(7);
for await (const batch of bufferedStream) {
console.log(`Processing a batch of ${batch.length} items:`, batch);
// In a real app, this could be a bulk database insert or some other batch operation
}
console.log("Finished processing all items.");
}
main();
ಈ ಉದಾಹರಣೆಯಲ್ಲಿ, async function* ಪುಟದಿಂದ ಪುಟಕ್ಕೆ ಡೇಟಾವನ್ನು ಸರಾಗವಾಗಿ ತರುತ್ತದೆ, ಆದರೆ ಐಟಂಗಳನ್ನು ಒಂದೊಂದಾಗಿ ನೀಡುತ್ತದೆ. ನಂತರ .buffer(7) ವಿಧಾನವು ಈ ವೈಯಕ್ತಿಕ ಐಟಂಗಳ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಬಳಸುತ್ತದೆ ಮತ್ತು ಅವುಗಳನ್ನು 7 ರ ಅರೇಗಳಾಗಿ ಗುಂಪು ಮಾಡುತ್ತದೆ, ಎಲ್ಲವೂ ಮೂಲದ ಅಸಿಂಕ್ರೊನಸ್ ಸ್ವರೂಪವನ್ನು ಗೌರವಿಸುತ್ತದೆ. ಫಲಿತಾಂಶದ ಬಫರ್ಡ್ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಬಳಸಲು ನಾವು for await...of ಲೂಪ್ ಅನ್ನು ಬಳಸುತ್ತೇವೆ. ಈ ಪ್ಯಾಟರ್ನ್ ಸಂಕೀರ್ಣ ಅಸಿಂಕ್ರೊನಸ್ ವರ್ಕ್ಫ್ಲೋಗಳನ್ನು ಸ್ವಚ್ಛ, ಓದಬಲ್ಲ ರೀತಿಯಲ್ಲಿ ಸಂಯೋಜಿಸಲು ನಂಬಲಾಗದಷ್ಟು ಶಕ್ತಿಯುತವಾಗಿದೆ.
ಸುಧಾರಿತ ಬಳಕೆಯ ಪ್ರಕರಣ: ಕನ್ಕರೆನ್ಸಿಯನ್ನು ನಿಯಂತ್ರಿಸುವುದು
buffer() ನ ಅತ್ಯಂತ ಆಕರ್ಷಕ ಬಳಕೆಯ ಪ್ರಕರಣಗಳಲ್ಲಿ ಒಂದು ಕನ್ಕರೆನ್ಸಿಯನ್ನು ನಿರ್ವಹಿಸುವುದು. ನೀವು 100 URL ಗಳನ್ನು ಫೆಚ್ ಮಾಡಬೇಕಾಗಿದೆ ಎಂದು ಕಲ್ಪಿಸಿಕೊಳ್ಳಿ, ಆದರೆ ನೀವು ಏಕಕಾಲದಲ್ಲಿ 100 ವಿನಂತಿಗಳನ್ನು ಕಳುಹಿಸಲು ಬಯಸುವುದಿಲ್ಲ, ಏಕೆಂದರೆ ಇದು ನಿಮ್ಮ ಸರ್ವರ್ ಅಥವಾ ರಿಮೋಟ್ API ಅನ್ನು ಓವರ್ಲೋಡ್ ಮಾಡಬಹುದು. ನೀವು ಅವುಗಳನ್ನು ನಿಯಂತ್ರಿತ, ಕನ್ಕರೆಂಟ್ ಬ್ಯಾಚ್ಗಳಲ್ಲಿ ಪ್ರೊಸೆಸ್ ಮಾಡಲು ಬಯಸುತ್ತೀರಿ.
buffer() ಅನ್ನು Promise.all() ಜೊತೆ ಸಂಯೋಜಿಸುವುದು ಇದಕ್ಕೆ ಪರಿಪೂರ್ಣ ಪರಿಹಾರವಾಗಿದೆ.
// Helper to simulate fetching a URL
async function fetchUrl(url) {
console.log(`Starting fetch for: ${url}`);
const delay = 1000 + Math.random() * 2000; // Random delay between 1-3 seconds
await new Promise(resolve => setTimeout(resolve, delay));
console.log(`Finished fetching: ${url}`);
return `Content for ${url}`;
}
async function processUrls() {
const urls = Array.from({ length: 15 }, (_, i) => `https://example.com/data/${i + 1}`);
// Get an iterator for the URLs
const urlIterator = urls[Symbol.iterator]();
// Buffer the URLs into chunks of 5. This will be our concurrency level.
const bufferedUrls = urlIterator.buffer(5);
for (const urlBatch of bufferedUrls) {
console.log(`
--- Starting a new concurrent batch of ${urlBatch.length} requests ---
`);
// Create an array of Promises by mapping over the batch
const promises = urlBatch.map(url => fetchUrl(url));
// Wait for all promises in the current batch to resolve
const results = await Promise.all(promises);
console.log(`--- Batch completed. Results:`, results);
// Process the results for this batch...
}
console.log("\nAll URLs have been processed.");
}
processUrls();
ಈ ಶಕ್ತಿಯುತ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ವಿಭಜಿಸೋಣ:
- ನಾವು URL ಗಳ ಅರೇಯೊಂದಿಗೆ ಪ್ರಾರಂಭಿಸುತ್ತೇವೆ.
- ನಾವು
urls[Symbol.iterator]()ಬಳಸಿ ಅರೇಯಿಂದ ಪ್ರಮಾಣಿತ ಸಿಂಕ್ರೊನಸ್ ಇಟರೇಟರ್ ಅನ್ನು ಪಡೆಯುತ್ತೇವೆ. urlIterator.buffer(5)ಒಂದು ಹೊಸ ಇಟರೇಟರ್ ಅನ್ನು ರಚಿಸುತ್ತದೆ, ಅದು ಒಂದು ಸಮಯದಲ್ಲಿ 5 URL ಗಳ ಅರೇಗಳನ್ನು ನೀಡುತ್ತದೆ.for...ofಲೂಪ್ ಈ ಬ್ಯಾಚ್ಗಳ ಮೇಲೆ ಇಟರೇಟ್ ಮಾಡುತ್ತದೆ.- ಲೂಪ್ನೊಳಗೆ,
urlBatch.map(fetchUrl)ತಕ್ಷಣವೇ ಬ್ಯಾಚ್ನಲ್ಲಿರುವ ಎಲ್ಲಾ 5 ಫೆಚ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಪ್ರಾರಂಭಿಸುತ್ತದೆ, Promises ಗಳ ಅರೇಯನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ. await Promise.all(promises)ಪ್ರಸ್ತುತ ಬ್ಯಾಚ್ನಲ್ಲಿರುವ ಎಲ್ಲಾ 5 ವಿನಂತಿಗಳು ಪೂರ್ಣಗೊಳ್ಳುವವರೆಗೆ ಲೂಪ್ನ ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯನ್ನು ವಿರಾಮಗೊಳಿಸುತ್ತದೆ.- ಬ್ಯಾಚ್ ಮುಗಿದ ನಂತರ, ಲೂಪ್ ಮುಂದಿನ 5 URL ಗಳ ಬ್ಯಾಚ್ಗೆ ಮುಂದುವರಿಯುತ್ತದೆ.
ಇದು ನಮಗೆ ಒಂದು ನಿಗದಿತ ಮಟ್ಟದ ಕನ್ಕರೆನ್ಸಿಯೊಂದಿಗೆ (ಈ ಸಂದರ್ಭದಲ್ಲಿ, ಒಂದು ಬಾರಿಗೆ 5) ಕಾರ್ಯಗಳನ್ನು ಪ್ರೊಸೆಸ್ ಮಾಡಲು ಸ್ವಚ್ಛ ಮತ್ತು ದೃಢವಾದ ಮಾರ್ಗವನ್ನು ನೀಡುತ್ತದೆ, ಸಮಾನಾಂತರ ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯ ಪ್ರಯೋಜನವನ್ನು ಪಡೆಯುವಾಗ ಸಂಪನ್ಮೂಲಗಳನ್ನು ಓವರ್ಲೋಡ್ ಮಾಡುವುದನ್ನು ತಡೆಯುತ್ತದೆ.
ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ಮೆಮೊರಿ ಪರಿಗಣನೆಗಳು
buffer() ಒಂದು ಶಕ್ತಿಯುತ ಸಾಧನವಾಗಿದ್ದರೂ, ಅದರ ಕಾರ್ಯಕ್ಷಮತೆಯ ಗುಣಲಕ್ಷಣಗಳ ಬಗ್ಗೆ ಗಮನ ಹರಿಸುವುದು ಮುಖ್ಯ.
- ಮೆಮೊರಿ ಬಳಕೆ: ಪ್ರಾಥಮಿಕ ಪರಿಗಣನೆಯು ನಿಮ್ಮ ಬಫರ್ನ ಗಾತ್ರವಾಗಿದೆ.
stream.buffer(10000)ನಂತಹ ಕಾಲ್ 10,000 ಐಟಂಗಳನ್ನು ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳುವ ಅರೇಗಳನ್ನು ರಚಿಸುತ್ತದೆ. ಪ್ರತಿ ಐಟಂ ದೊಡ್ಡ ಆಬ್ಜೆಕ್ಟ್ ಆಗಿದ್ದರೆ, ಇದು ಗಮನಾರ್ಹ ಪ್ರಮಾಣದ ಮೆಮೊರಿಯನ್ನು ಬಳಸಬಹುದು. ಬ್ಯಾಚ್ ಪ್ರೊಸೆಸಿಂಗ್ನ ದಕ್ಷತೆ ಮತ್ತು ಮೆಮೊರಿ ನಿರ್ಬಂಧಗಳ ನಡುವೆ ಸಮತೋಲನವನ್ನು ಕಾಯ್ದುಕೊಳ್ಳುವ ಬಫರ್ ಗಾತ್ರವನ್ನು ಆಯ್ಕೆ ಮಾಡುವುದು ನಿರ್ಣಾಯಕವಾಗಿದೆ. - ಲೇಜಿ ಇವ್ಯಾಲ್ಯುಯೇಷನ್ ಪ್ರಮುಖವಾಗಿದೆ:
buffer()ಲೇಜಿ ಎಂಬುದನ್ನು ನೆನಪಿಡಿ. ಇದು ಪ್ರಸ್ತುತ ಬಫರ್ಗಾಗಿ ವಿನಂತಿಯನ್ನು ಪೂರೈಸಲು ಮೂಲ ಇಟರೇಟರ್ನಿಂದ ಸಾಕಷ್ಟು ಐಟಂಗಳನ್ನು ಮಾತ್ರ ಎಳೆಯುತ್ತದೆ. ಇದು ಸಂಪೂರ್ಣ ಮೂಲ ಸ್ಟ್ರೀಮ್ ಅನ್ನು ಮೆಮೊರಿಗೆ ಓದುವುದಿಲ್ಲ. ಇದು RAM ಗೆ ಹೊಂದಿಕೊಳ್ಳದ ಅತ್ಯಂತ ದೊಡ್ಡ ಡೇಟಾಸೆಟ್ಗಳನ್ನು ಪ್ರೊಸೆಸ್ ಮಾಡಲು ಸೂಕ್ತವಾಗಿಸುತ್ತದೆ. - ಸಿಂಕ್ರೊನಸ್ ವರ್ಸಸ್ ಅಸಿಂಕ್ರೊನಸ್: ವೇಗದ ಮೂಲ ಇಟರೇಟರ್ನೊಂದಿಗೆ ಸಿಂಕ್ರೊನಸ್ ಸಂದರ್ಭದಲ್ಲಿ, ಸಹಾಯಕದ ಓವರ್ಹೆಡ್ ನಗಣ್ಯವಾಗಿರುತ್ತದೆ. ಅಸಿಂಕ್ರೊನಸ್ ಸಂದರ್ಭದಲ್ಲಿ, ಕಾರ್ಯಕ್ಷಮತೆಯು ಸಾಮಾನ್ಯವಾಗಿ ಬಫರಿಂಗ್ ಲಾಜಿಕ್ಗಿಂತ ಹೆಚ್ಚಾಗಿ ಆಧಾರವಾಗಿರುವ ಅಸಿಂಕ್ ಇಟರೇಟರ್ನ I/O (ಉದಾ., ನೆಟ್ವರ್ಕ್ ಅಥವಾ ಫೈಲ್ ಸಿಸ್ಟಮ್ ಲೇಟೆನ್ಸಿ) ದಿಂದ ಪ್ರಾಬಲ್ಯ ಹೊಂದಿರುತ್ತದೆ. ಸಹಾಯಕವು ಕೇವಲ ಡೇಟಾದ ಹರಿವನ್ನು ಸಂಯೋಜಿಸುತ್ತದೆ.
ವಿಶಾಲ ಸಂದರ್ಭ: ಇಟರೇಟರ್ ಸಹಾಯಕಗಳ ಕುಟುಂಬ
buffer() ಉದ್ದೇಶಿತ ಇಟರೇಟರ್ ಸಹಾಯಕಗಳ ಕುಟುಂಬದ ಕೇವಲ ಒಬ್ಬ ಸದಸ್ಯ. ಈ ಕುಟುಂಬದಲ್ಲಿ ಅದರ ಸ್ಥಾನವನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ನಲ್ಲಿ ಡೇಟಾ ಪ್ರೊಸೆಸಿಂಗ್ಗಾಗಿ ಹೊಸ ಮಾದರಿಯನ್ನು ಎತ್ತಿ ತೋರಿಸುತ್ತದೆ. ಇತರ ಉದ್ದೇಶಿತ ಸಹಾಯಕಗಳು ಸೇರಿವೆ:
.map(fn): ಇಟರೇಟರ್ನಿಂದ ನೀಡಲಾದ ಪ್ರತಿಯೊಂದು ಐಟಂ ಅನ್ನು ಪರಿವರ್ತಿಸುತ್ತದೆ..filter(fn): ಪರೀಕ್ಷೆಯಲ್ಲಿ ಉತ್ತೀರ್ಣರಾದ ಐಟಂಗಳನ್ನು ಮಾತ್ರ ನೀಡುತ್ತದೆ..take(n): ಮೊದಲnಐಟಂಗಳನ್ನು ನೀಡುತ್ತದೆ ಮತ್ತು ನಂತರ ನಿಲ್ಲಿಸುತ್ತದೆ..drop(n): ಮೊದಲnಐಟಂಗಳನ್ನು ಬಿಟ್ಟು ಉಳಿದವನ್ನು ನೀಡುತ್ತದೆ..flatMap(fn): ಪ್ರತಿ ಐಟಂ ಅನ್ನು ಇಟರೇಟರ್ಗೆ ಮ್ಯಾಪ್ ಮಾಡುತ್ತದೆ ಮತ್ತು ನಂತರ ಫಲಿತಾಂಶಗಳನ್ನು ಫ್ಲಾಟನ್ ಮಾಡುತ್ತದೆ..reduce(fn, initial): ಇಟರೇಟರ್ ಅನ್ನು ಒಂದೇ ಮೌಲ್ಯಕ್ಕೆ ಇಳಿಸಲು ಒಂದು ಟರ್ಮಿನಲ್ ಕಾರ್ಯಾಚರಣೆ.
ನಿಜವಾದ ಶಕ್ತಿಯು ಈ ವಿಧಾನಗಳನ್ನು ಒಟ್ಟಿಗೆ ಚೈನ್ ಮಾಡುವುದರಿಂದ ಬರುತ್ತದೆ. ಉದಾಹರಣೆಗೆ:
// A hypothetical chain of operations
const finalResult = await sensorDataStream // an async iterator
.map(reading => reading * 1.8 + 32) // Convert Celsius to Fahrenheit
.filter(tempF => tempF > 75) // Only care about warm temperatures
.buffer(60) // Batch readings into 1-minute chunks (if one reading per second)
.map(minuteBatch => calculateAverage(minuteBatch)) // Get the average for each minute
.take(10) // Only process the first 10 minutes of data
.toArray(); // Another proposed helper to collect results into an array
ಸ್ಟ್ರೀಮ್ ಪ್ರೊಸೆಸಿಂಗ್ಗಾಗಿ ಈ ನಿರರ್ಗಳ, ಡಿಕ್ಲರೇಟಿವ್ ಶೈಲಿಯು ಅಭಿವ್ಯಕ್ತಿಶೀಲ, ಓದಲು ಸುಲಭ, ಮತ್ತು ಸಮಾನವಾದ ಇಂಪರೇಟಿವ್ ಕೋಡ್ಗಿಂತ ಕಡಿಮೆ ದೋಷಗಳಿಗೆ ಗುರಿಯಾಗುತ್ತದೆ. ಇದು ಇತರ ಪರಿಸರ ವ್ಯವಸ್ಥೆಗಳಲ್ಲಿ ದೀರ್ಘಕಾಲದಿಂದ ಜನಪ್ರಿಯವಾಗಿರುವ ಫಂಕ್ಷನಲ್ ಪ್ರೋಗ್ರಾಮಿಂಗ್ ಮಾದರಿಯನ್ನು ನೇರವಾಗಿ ಮತ್ತು ಸ್ಥಳೀಯವಾಗಿ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ಗೆ ತರುತ್ತದೆ.
ತೀರ್ಮಾನ: ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಡೇಟಾ ಪ್ರೊಸೆಸಿಂಗ್ಗೆ ಒಂದು ಹೊಸ ಯುಗ
Iterator.prototype.buffer() ಸಹಾಯಕವು ಕೇವಲ ಒಂದು ಅನುಕೂಲಕರ ಉಪಯುಕ್ತತೆಗಿಂತ ಹೆಚ್ಚಾಗಿದೆ; ಇದು ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಡೆವಲಪರ್ಗಳು ಡೇಟಾದ ಅನುಕ್ರಮಗಳು ಮತ್ತು ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ಹೇಗೆ ನಿರ್ವಹಿಸಬಹುದು ಎಂಬುದಕ್ಕೆ ಒಂದು ಮೂಲಭೂತ ವರ್ಧನೆಯನ್ನು ಪ್ರತಿನಿಧಿಸುತ್ತದೆ. ಐಟಂಗಳನ್ನು ಬ್ಯಾಚ್ ಮಾಡಲು ಡಿಕ್ಲರೇಟಿವ್, ಲೇಜಿ ಮತ್ತು ಸಂಯೋಜಿಸಬಹುದಾದ ಮಾರ್ಗವನ್ನು ಒದಗಿಸುವ ಮೂಲಕ, ಇದು ಸೊಬಗು ಮತ್ತು ದಕ್ಷತೆಯೊಂದಿಗೆ ಸಾಮಾನ್ಯ ಮತ್ತು ಆಗಾಗ್ಗೆ ಟ್ರಿಕಿ ಸಮಸ್ಯೆಯನ್ನು ಪರಿಹರಿಸುತ್ತದೆ.
ಪ್ರಮುಖ ಅಂಶಗಳು:
- ಕೋಡ್ ಅನ್ನು ಸರಳಗೊಳಿಸುತ್ತದೆ: ಇದು ವಿವರವಾದ, ದೋಷ-ಸಾಧ್ಯತೆಯ ಮ್ಯಾನುಯಲ್ ಬಫರಿಂಗ್ ಲಾಜಿಕ್ ಅನ್ನು ಒಂದೇ, ಸ್ಪಷ್ಟವಾದ ಮೆಥಡ್ ಕಾಲ್ನೊಂದಿಗೆ ಬದಲಾಯಿಸುತ್ತದೆ.
- ದಕ್ಷ ಬ್ಯಾಚಿಂಗ್ ಅನ್ನು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ: ಡೇಟಾಬೇಸ್ ಇನ್ಸರ್ಟ್ಗಳು, API ಕಾಲ್ಗಳು, ಅಥವಾ ಫೈಲ್ ರೈಟ್ಗಳಂತಹ ಬಲ್ಕ್ ಕಾರ್ಯಾಚರಣೆಗಳಿಗಾಗಿ ಡೇಟಾವನ್ನು ಗುಂಪು ಮಾಡಲು ಇದು ಪರಿಪೂರ್ಣ ಸಾಧನವಾಗಿದೆ.
- ಅಸಿಂಕ್ರೊನಸ್ ಕಂಟ್ರೋಲ್ ಫ್ಲೋನಲ್ಲಿ ಉತ್ತಮವಾಗಿದೆ: ಇದು ಅಸಿಂಕ್ ಇಟರೇಟರ್ಗಳು ಮತ್ತು
for await...ofಲೂಪ್ನೊಂದಿಗೆ ಸರಾಗವಾಗಿ ಸಂಯೋಜನೆಗೊಳ್ಳುತ್ತದೆ, ಸಂಕೀರ್ಣ ಅಸಿಂಕ್ ಡೇಟಾ ಪೈಪ್ಲೈನ್ಗಳನ್ನು ನಿರ್ವಹಿಸಬಲ್ಲದು ಮಾಡುತ್ತದೆ. - ಕನ್ಕರೆನ್ಸಿಯನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ:
Promise.allಜೊತೆ ಸಂಯೋಜಿಸಿದಾಗ, ಇದು ಸಮಾನಾಂತರ ಕಾರ್ಯಾಚರಣೆಗಳ ಸಂಖ್ಯೆಯನ್ನು ನಿಯಂತ್ರಿಸಲು ಒಂದು ಶಕ್ತಿಯುತ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಒದಗಿಸುತ್ತದೆ. - ಮೆಮೊರಿ ದಕ್ಷತೆ: ಅದರ ಲೇಜಿ ಸ್ವಭಾವವು ಅಧಿಕ ಮೆಮೊರಿಯನ್ನು ಬಳಸದೆ ಯಾವುದೇ ಗಾತ್ರದ ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ಪ್ರೊಸೆಸ್ ಮಾಡಬಹುದೆಂದು ಖಚಿತಪಡಿಸುತ್ತದೆ.
Iterator Helpers ಪ್ರಸ್ತಾಪವು ಪ್ರಮಾಣೀಕರಣದತ್ತ ಸಾಗುತ್ತಿರುವಾಗ, buffer() ನಂತಹ ಸಾಧನಗಳು ಆಧುನಿಕ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಡೆವಲಪರ್ನ ಟೂಲ್ಕಿಟ್ನ ಪ್ರಮುಖ ಭಾಗವಾಗುತ್ತವೆ. ಈ ಹೊಸ ಸಾಮರ್ಥ್ಯಗಳನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳುವ ಮೂಲಕ, ನಾವು ಕೇವಲ ಹೆಚ್ಚು ಕಾರ್ಯಕ್ಷಮತೆ ಮತ್ತು ದೃಢವಾದ ಕೋಡ್ ಅನ್ನು ಬರೆಯಬಹುದು, ಆದರೆ ಗಣನೀಯವಾಗಿ ಸ್ವಚ್ಛ ಮತ್ತು ಹೆಚ್ಚು ಅಭಿವ್ಯಕ್ತಿಶೀಲ ಕೋಡ್ ಅನ್ನು ಸಹ ಬರೆಯಬಹುದು. ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ನಲ್ಲಿ ಡೇಟಾ ಪ್ರೊಸೆಸಿಂಗ್ನ ಭವಿಷ್ಯವು ಸ್ಟ್ರೀಮಿಂಗ್ ಆಗಿದೆ, ಮತ್ತು buffer() ನಂತಹ ಸಹಾಯಕಗಳೊಂದಿಗೆ, ಅದನ್ನು ನಿಭಾಯಿಸಲು ನಾವು ಹಿಂದೆಂದಿಗಿಂತಲೂ ಉತ್ತಮವಾಗಿ ಸಿದ್ಧರಾಗಿದ್ದೇವೆ.