ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ಮತ್ತು ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ಗೆ ಒಂದು ಸಮಗ್ರ ಮಾರ್ಗದರ್ಶಿ. ಕಸ್ಟಮ್ ಇಟರೇಟರ್ಗಳನ್ನು ಹೇಗೆ ರಚಿಸುವುದು ಮತ್ತು ನಿಮ್ಮ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಹೇಗೆ ಸುಧಾರಿಸುವುದು ಎಂದು ತಿಳಿಯಿರಿ.
ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು: ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ನಲ್ಲಿ ಪಾಂಡಿತ್ಯ
ECMAScript 6 (ES6) ನಲ್ಲಿ ಪರಿಚಯಿಸಲಾದ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು, ಹೆಚ್ಚು ಸಂಕ್ಷಿಪ್ತ ಮತ್ತು ಓದಬಲ್ಲ ರೀತಿಯಲ್ಲಿ ಇಟರೇಟರ್ಗಳನ್ನು ರಚಿಸಲು ಪ್ರಬಲವಾದ ಯಾಂತ್ರಿಕತೆಯನ್ನು ಒದಗಿಸುತ್ತವೆ. ಅವು ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ನೊಂದಿಗೆ ಮನಬಂದಂತೆ ಸಂಯೋಜನೆಗೊಳ್ಳುತ್ತವೆ, ಸಂಕೀರ್ಣ ಡೇಟಾ ರಚನೆಗಳನ್ನು ಮತ್ತು ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಸುಲಭವಾಗಿ ನಿರ್ವಹಿಸಬಲ್ಲ ಕಸ್ಟಮ್ ಇಟರೇಟರ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು ನಿಮಗೆ ಅನುವು ಮಾಡಿಕೊಡುತ್ತವೆ. ಈ ಲೇಖನವು ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳ ಜಟಿಲತೆಗಳು, ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್, ಮತ್ತು ಅವುಗಳ ಅನ್ವಯವನ್ನು ವಿವರಿಸಲು ಪ್ರಾಯೋಗಿಕ ಉದಾಹರಣೆಗಳನ್ನು ಪರಿಶೀಲಿಸುತ್ತದೆ.
ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ ಅನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳ ಬಗ್ಗೆ ತಿಳಿಯುವ ಮೊದಲು, ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ ಅನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವುದು ಬಹಳ ಮುಖ್ಯ. ಇದು ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ನಲ್ಲಿ ಇಟರೇಬಲ್ ಡೇಟಾ ರಚನೆಗಳಿಗೆ ಅಡಿಪಾಯವಾಗಿದೆ. ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ ಒಂದು ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಹೇಗೆ ಇಟರೇಟ್ ಮಾಡಬಹುದು ಎಂಬುದನ್ನು ವ್ಯಾಖ್ಯಾನಿಸುತ್ತದೆ, ಅಂದರೆ ಅದರ ಅಂಶಗಳನ್ನು ಅನುಕ್ರಮವಾಗಿ ಪ್ರವೇಶಿಸಬಹುದು.
ಇಟರೇಬಲ್ ಪ್ರೊಟೊಕಾಲ್
ಒಂದು ಆಬ್ಜೆಕ್ಟ್ @@iterator ಮೆಥಡ್ (Symbol.iterator) ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿದರೆ ಅದನ್ನು ಇಟರೇಬಲ್ ಎಂದು ಪರಿಗಣಿಸಲಾಗುತ್ತದೆ. ಈ ಮೆಥಡ್ ಒಂದು ಇಟರೇಟರ್ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಹಿಂತಿರುಗಿಸಬೇಕು.
ಒಂದು ಸರಳ ಇಟರೇಬಲ್ ಆಬ್ಜೆಕ್ಟ್ನ ಉದಾಹರಣೆ:
const myIterable = {
data: [1, 2, 3],
[Symbol.iterator]() {
let index = 0;
return {
next() {
if (index < myIterable.data.length) {
return { value: myIterable.data[index++], done: false };
} else {
return { value: undefined, done: true };
}
}
};
}
};
for (const item of myIterable) {
console.log(item); // Output: 1, 2, 3
}
ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್
ಒಂದು ಇಟರೇಟರ್ ಆಬ್ಜೆಕ್ಟ್ next() ಮೆಥಡ್ ಅನ್ನು ಹೊಂದಿರಬೇಕು. next() ಮೆಥಡ್ ಎರಡು ಪ್ರಾಪರ್ಟಿಗಳಿರುವ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ:
value: ಅನುಕ್ರಮದಲ್ಲಿ ಮುಂದಿನ ಮೌಲ್ಯ.done: ಇಟರೇಟರ್ ಅನುಕ್ರಮದ ಅಂತ್ಯವನ್ನು ತಲುಪಿದೆಯೇ ಎಂದು ಸೂಚಿಸುವ ಬೂಲಿಯನ್.trueಅಂತ್ಯವನ್ನು ಸೂಚಿಸುತ್ತದೆ;falseಎಂದರೆ ಇನ್ನೂ ಮೌಲ್ಯಗಳನ್ನು ಹಿಂಪಡೆಯಲು ಬಾಕಿ ಇದೆ ಎಂದು ಅರ್ಥ.
ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ for...of ಲೂಪ್ಗಳು ಮತ್ತು ಸ್ಪ್ರೆಡ್ ಆಪರೇಟರ್ (...) ನಂತಹ ಅಂತರ್ನಿರ್ಮಿತ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಕಸ್ಟಮ್ ಡೇಟಾ ರಚನೆಗಳೊಂದಿಗೆ ಸರಾಗವಾಗಿ ಕೆಲಸ ಮಾಡಲು ಅನುಮತಿಸುತ್ತದೆ.
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳ ಪರಿಚಯ
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ಇಟರೇಟರ್ಗಳನ್ನು ರಚಿಸಲು ಹೆಚ್ಚು ಸೊಗಸಾದ ಮತ್ತು ಸಂಕ್ಷಿಪ್ತ ಮಾರ್ಗವನ್ನು ಒದಗಿಸುತ್ತವೆ. ಅವುಗಳನ್ನು function* ಸಿಂಟ್ಯಾಕ್ಸ್ ಬಳಸಿ ಘೋಷಿಸಲಾಗುತ್ತದೆ.
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳ ಸಿಂಟ್ಯಾಕ್ಸ್
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ನ ಮೂಲ ಸಿಂಟ್ಯಾಕ್ಸ್ ಈ ಕೆಳಗಿನಂತಿರುತ್ತದೆ:
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}
const iterator = myGenerator();
console.log(iterator.next()); // Output: { value: 1, done: false }
console.log(iterator.next()); // Output: { value: 2, done: false }
console.log(iterator.next()); // Output: { value: 3, done: false }
console.log(iterator.next()); // Output: { value: undefined, done: true }
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳ ಪ್ರಮುಖ ಗುಣಲಕ್ಷಣಗಳು:
- ಅವುಗಳನ್ನು
functionಬದಲಿಗೆfunction*ನೊಂದಿಗೆ ಘೋಷಿಸಲಾಗುತ್ತದೆ. - ಅವು ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯನ್ನು ವಿರಾಮಗೊಳಿಸಲು ಮತ್ತು ಮೌಲ್ಯವನ್ನು ಹಿಂತಿರುಗಿಸಲು
yieldಕೀವರ್ಡ್ ಅನ್ನು ಬಳಸುತ್ತವೆ. - ಇಟರೇಟರ್ನಲ್ಲಿ
next()ಅನ್ನು ಕರೆದಾಗ마다, ಜನರೇಟರ್ ಫಂಕ್ಷನ್ ಅದು ನಿಲ್ಲಿಸಿದ್ದ ಸ್ಥಳದಿಂದ ಮುಂದಿನyieldಸ್ಟೇಟ್ಮೆಂಟ್ ಸಿಗುವವರೆಗೆ ಅಥವಾ ಫಂಕ್ಷನ್ ಹಿಂತಿರುಗುವವರೆಗೆ ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯನ್ನು ಪುನರಾರಂಭಿಸುತ್ತದೆ. - ಜನರೇಟರ್ ಫಂಕ್ಷನ್ ಕಾರ್ಯಗತಗೊಳಿಸುವಿಕೆಯನ್ನು ಮುಗಿಸಿದಾಗ (ಅಂತ್ಯವನ್ನು ತಲುಪುವ ಮೂಲಕ ಅಥವಾ
returnಸ್ಟೇಟ್ಮೆಂಟ್ ಎದುರಾದಾಗ), ಹಿಂತಿರುಗಿದ ಆಬ್ಜೆಕ್ಟ್ನdoneಪ್ರಾಪರ್ಟಿtrueಆಗುತ್ತದೆ.
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ ಅನ್ನು ಹೇಗೆ ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತವೆ
ನೀವು ಜನರೇಟರ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಕರೆದಾಗ, ಅದು ತಕ್ಷಣವೇ ಕಾರ್ಯಗತಗೊಳ್ಳುವುದಿಲ್ಲ. ಬದಲಿಗೆ, ಅದು ಇಟರೇಟರ್ ಆಬ್ಜೆಕ್ಟ್ ಅನ್ನು ಹಿಂತಿರುಗಿಸುತ್ತದೆ. ಈ ಇಟರೇಟರ್ ಆಬ್ಜೆಕ್ಟ್ ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುತ್ತದೆ. ಪ್ರತಿಯೊಂದು yield ಸ್ಟೇಟ್ಮೆಂಟ್ ಇಟರೇಟರ್ನ next() ಮೆಥಡ್ಗಾಗಿ ಒಂದು ಮೌಲ್ಯವನ್ನು ಉತ್ಪಾದಿಸುತ್ತದೆ. ಜನರೇಟರ್ ಫಂಕ್ಷನ್ ಆಂತರಿಕ ಸ್ಥಿತಿಯನ್ನು ನಿರ್ವಹಿಸುತ್ತದೆ ಮತ್ತು ಅದರ ಪ್ರಗತಿಯನ್ನು ಟ್ರ್ಯಾಕ್ ಮಾಡುತ್ತದೆ, ಇದರಿಂದ ಕಸ್ಟಮ್ ಇಟರೇಟರ್ಗಳನ್ನು ರಚಿಸುವುದು ಸರಳವಾಗುತ್ತದೆ.
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳ ಪ್ರಾಯೋಗಿಕ ಉದಾಹರಣೆಗಳು
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳ ಶಕ್ತಿ ಮತ್ತು ಬಹುಮುಖತೆಯನ್ನು ಪ್ರದರ್ಶಿಸುವ ಕೆಲವು ಪ್ರಾಯೋಗಿಕ ಉದಾಹರಣೆಗಳನ್ನು ನೋಡೋಣ.
1. ಸಂಖ್ಯೆಗಳ ಅನುಕ್ರಮವನ್ನು ರಚಿಸುವುದು
ಈ ಉದಾಹರಣೆಯು ನಿರ್ದಿಷ್ಟ ಶ್ರೇಣಿಯೊಳಗೆ ಸಂಖ್ಯೆಗಳ ಅನುಕ್ರಮವನ್ನು ರಚಿಸುವ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಹೇಗೆ ರಚಿಸುವುದು ಎಂದು ತೋರಿಸುತ್ತದೆ.
function* numberSequence(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
const sequence = numberSequence(10, 15);
for (const num of sequence) {
console.log(num); // Output: 10, 11, 12, 13, 14, 15
}
2. ಟ್ರೀ ರಚನೆಯ ಮೇಲೆ ಇಟರೇಟ್ ಮಾಡುವುದು
ಟ್ರೀಗಳಂತಹ ಸಂಕೀರ್ಣ ಡೇಟಾ ರಚನೆಗಳನ್ನು ಕ್ರಮಿಸಲು ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ವಿಶೇಷವಾಗಿ ಉಪಯುಕ್ತವಾಗಿವೆ. ಈ ಉದಾಹರಣೆಯು ಬೈನರಿ ಟ್ರೀಯ ನೋಡ್ಗಳ ಮೇಲೆ ಹೇಗೆ ಇಟರೇಟ್ ಮಾಡುವುದು ಎಂಬುದನ್ನು ತೋರಿಸುತ್ತದೆ.
class TreeNode {
constructor(value) {
this.value = value;
this.left = null;
this.right = null;
}
}
function* treeTraversal(node) {
if (node) {
yield* treeTraversal(node.left); // Recursive call for left subtree
yield node.value; // Yield the current node's value
yield* treeTraversal(node.right); // Recursive call for right subtree
}
}
// Create a sample binary tree
const root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(5);
// Iterate over the tree using the generator function
const treeIterator = treeTraversal(root);
for (const value of treeIterator) {
console.log(value); // Output: 4, 2, 5, 1, 3 (In-order traversal)
}
ಈ ಉದಾಹರಣೆಯಲ್ಲಿ, yield* ಅನ್ನು ಇನ್ನೊಂದು ಇಟರೇಟರ್ಗೆ ನಿಯೋಜಿಸಲು ಬಳಸಲಾಗುತ್ತದೆ. ಇದು ರಿಕರ್ಸಿವ್ ಇಟರೇಷನ್ಗೆ ನಿರ್ಣಾಯಕವಾಗಿದೆ, ಇದು ಜನರೇಟರ್ಗೆ ಸಂಪೂರ್ಣ ಟ್ರೀ ರಚನೆಯನ್ನು ಕ್ರಮಿಸಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ.
3. ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ನಿರ್ವಹಿಸುವುದು
ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಹೆಚ್ಚು ಅನುಕ್ರಮ ಮತ್ತು ಓದಬಲ್ಲ ರೀತಿಯಲ್ಲಿ ನಿರ್ವಹಿಸಲು ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳನ್ನು ಪ್ರಾಮಿಸಸ್ಗಳೊಂದಿಗೆ (Promises) ಸಂಯೋಜಿಸಬಹುದು. ಎಪಿಐನಿಂದ (API) ಡೇಟಾವನ್ನು ಪಡೆಯುವಂತಹ ಕಾರ್ಯಗಳಿಗೆ ಇದು ವಿಶೇಷವಾಗಿ ಉಪಯುಕ್ತವಾಗಿದೆ.
async function fetchData(url) {
const response = await fetch(url);
const data = await response.json();
return data;
}
function* dataFetcher(urls) {
for (const url of urls) {
try {
const data = yield fetchData(url);
yield data;
} catch (error) {
console.error("Error fetching data from", url, error);
yield null; // Or handle the error as needed
}
}
}
async function runDataFetcher() {
const urls = [
"https://jsonplaceholder.typicode.com/todos/1",
"https://jsonplaceholder.typicode.com/posts/1",
"https://jsonplaceholder.typicode.com/users/1"
];
const dataIterator = dataFetcher(urls);
for (const promise of dataIterator) {
const data = await promise; // Await the promise returned by yield
if (data) {
console.log("Fetched data:", data);
} else {
console.log("Failed to fetch data.");
}
}
}
runDataFetcher();
ಈ ಉದಾಹರಣೆಯು ಅಸಿಂಕ್ರೋನಸ್ ಇಟರೇಷನ್ ಅನ್ನು ಪ್ರದರ್ಶಿಸುತ್ತದೆ. dataFetcher ಜನರೇಟರ್ ಫಂಕ್ಷನ್ ಪಡೆದ ಡೇಟಾಗೆ ಪರಿಹಾರ ನೀಡುವ ಪ್ರಾಮಿಸಸ್ಗಳನ್ನು (Promises) ಯೀಲ್ಡ್ ಮಾಡುತ್ತದೆ. ನಂತರ runDataFetcher ಫಂಕ್ಷನ್ ಈ ಪ್ರಾಮಿಸಸ್ಗಳ ಮೂಲಕ ಇಟರೇಟ್ ಮಾಡುತ್ತದೆ, ಡೇಟಾವನ್ನು ಪ್ರೊಸೆಸ್ ಮಾಡುವ ಮೊದಲು ಪ್ರತಿಯೊಂದಕ್ಕೂ ಕಾಯುತ್ತದೆ. ಈ ವಿಧಾನವು ಅಸಿಂಕ್ರೋನಸ್ ಕೋಡ್ ಅನ್ನು ಹೆಚ್ಚು ಸಿಂಕ್ರೋನಸ್ ಆಗಿ ಕಾಣುವಂತೆ ಮಾಡಿ ಸರಳಗೊಳಿಸುತ್ತದೆ.
4. ಅನಂತ ಅನುಕ್ರಮಗಳು
ಅನಂತ ಅನುಕ್ರಮಗಳನ್ನು ಪ್ರತಿನಿಧಿಸಲು ಜನರೇಟರ್ಗಳು ಪರಿಪೂರ್ಣವಾಗಿವೆ, ಇವು ಎಂದಿಗೂ ಕೊನೆಗೊಳ್ಳದ ಅನುಕ್ರಮಗಳಾಗಿವೆ. ಅವು ವಿನಂತಿಸಿದಾಗ ಮಾತ್ರ ಮೌಲ್ಯಗಳನ್ನು ಉತ್ಪಾದಿಸುವುದರಿಂದ, ಅವು ವಿಪರೀತ ಮೆಮೊರಿಯನ್ನು ಬಳಸದೆ ಅನಂತ ದೀರ್ಘ ಅನುಕ್ರಮಗಳನ್ನು ನಿರ್ವಹಿಸಬಲ್ಲವು.
function* fibonacciSequence() {
let a = 0, b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const fibonacci = fibonacciSequence();
// Get the first 10 Fibonacci numbers
for (let i = 0; i < 10; i++) {
console.log(fibonacci.next().value); // Output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
}
ಈ ಉದಾಹರಣೆಯು ಅನಂತ ಫಿಬೊನಾಚಿ ಅನುಕ್ರಮವನ್ನು ಹೇಗೆ ರಚಿಸುವುದು ಎಂದು ತೋರಿಸುತ್ತದೆ. ಜನರೇಟರ್ ಫಂಕ್ಷನ್ ಫಿಬೊನಾಚಿ ಸಂಖ್ಯೆಗಳನ್ನು ಅನಿರ್ದಿಷ್ಟವಾಗಿ ಯೀಲ್ಡ್ ಮಾಡುವುದನ್ನು ಮುಂದುವರಿಸುತ್ತದೆ. ಆಚರಣೆಯಲ್ಲಿ, ಅನಂತ ಲೂಪ್ ಅಥವಾ ಮೆಮೊರಿ ಖಾಲಿಯಾಗುವುದನ್ನು ತಪ್ಪಿಸಲು ನೀವು ಸಾಮಾನ್ಯವಾಗಿ ಹಿಂಪಡೆಯುವ ಮೌಲ್ಯಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮಿತಿಗೊಳಿಸುತ್ತೀರಿ.
5. ಕಸ್ಟಮ್ ರೇಂಜ್ ಫಂಕ್ಷನ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸುವುದು
ಜನರೇಟರ್ಗಳನ್ನು ಬಳಸಿ ಪೈಥಾನ್ನ ಅಂತರ್ನಿರ್ಮಿತ ರೇಂಜ್ ಫಂಕ್ಷನ್ನಂತೆಯೇ ಕಸ್ಟಮ್ ರೇಂಜ್ ಫಂಕ್ಷನ್ ಅನ್ನು ರಚಿಸಿ.
function* range(start, end, step = 1) {
if (step > 0) {
for (let i = start; i < end; i += step) {
yield i;
}
} else if (step < 0) {
for (let i = start; i > end; i += step) {
yield i;
}
}
}
// Generate numbers from 0 to 5 (exclusive)
for (const num of range(0, 5)) {
console.log(num); // Output: 0, 1, 2, 3, 4
}
// Generate numbers from 10 to 0 (exclusive) in reverse order
for (const num of range(10, 0, -2)) {
console.log(num); // Output: 10, 8, 6, 4, 2
}
ಸುಧಾರಿತ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ ತಂತ್ರಗಳು
1. ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳಲ್ಲಿ `return` ಬಳಕೆ
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ನಲ್ಲಿನ return ಸ್ಟೇಟ್ಮೆಂಟ್ ಇಟರೇಷನ್ನ ಅಂತ್ಯವನ್ನು ಸೂಚಿಸುತ್ತದೆ. return ಸ್ಟೇಟ್ಮೆಂಟ್ ಎದುರಾದಾಗ, ಇಟರೇಟರ್ನ next() ಮೆಥಡ್ನ done ಪ್ರಾಪರ್ಟಿ true ಗೆ ಸೆಟ್ ಆಗುತ್ತದೆ, ಮತ್ತು value ಪ್ರಾಪರ್ಟಿ return ಸ್ಟೇಟ್ಮೆಂಟ್ ಹಿಂತಿರುಗಿಸಿದ ಮೌಲ್ಯಕ್ಕೆ ಸೆಟ್ ಆಗುತ್ತದೆ (ಯಾವುದಾದರೂ ಇದ್ದರೆ).
function* myGenerator() {
yield 1;
yield 2;
return 3; // End of iteration
yield 4; // This will not be executed
}
const iterator = myGenerator();
console.log(iterator.next()); // Output: { value: 1, done: false }
console.log(iterator.next()); // Output: { value: 2, done: false }
console.log(iterator.next()); // Output: { value: 3, done: true }
console.log(iterator.next()); // Output: { value: undefined, done: true }
2. ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳಲ್ಲಿ `throw` ಬಳಕೆ
ಇಟರೇಟರ್ ಆಬ್ಜೆಕ್ಟ್ನಲ್ಲಿನ throw ಮೆಥಡ್ ನಿಮಗೆ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗೆ ಒಂದು ಎಕ್ಸೆಪ್ಶನ್ ಅನ್ನು ಇಂಜೆಕ್ಟ್ ಮಾಡಲು ಅನುಮತಿಸುತ್ತದೆ. ಇದು ದೋಷಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಅಥವಾ ಜನರೇಟರ್ ಒಳಗೆ ನಿರ್ದಿಷ್ಟ ಸ್ಥಿತಿಗಳನ್ನು ಸೂಚಿಸಲು ಉಪಯುಕ್ತವಾಗಬಹುದು.
function* myGenerator() {
try {
yield 1;
yield 2;
} catch (error) {
console.error("Caught an error:", error);
}
yield 3;
}
const iterator = myGenerator();
console.log(iterator.next()); // Output: { value: 1, done: false }
iterator.throw(new Error("Something went wrong!")); // Inject an error
console.log(iterator.next()); // Output: { value: 3, done: false }
console.log(iterator.next()); // Output: { value: undefined, done: true }
3. `yield*` ನೊಂದಿಗೆ ಇನ್ನೊಂದು ಇಟರೇಬಲ್ಗೆ ನಿಯೋಜಿಸುವುದು
ಟ್ರೀ ಟ್ರಾವರ್ಸಲ್ ಉದಾಹರಣೆಯಲ್ಲಿ ನೋಡಿದಂತೆ, yield* ಸಿಂಟ್ಯಾಕ್ಸ್ ಇನ್ನೊಂದು ಇಟರೇಬಲ್ಗೆ (ಅಥವಾ ಇನ್ನೊಂದು ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗೆ) ನಿಯೋಜಿಸಲು ನಿಮಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ಇಟರೇಟರ್ಗಳನ್ನು ಸಂಯೋಜಿಸಲು ಮತ್ತು ಸಂಕೀರ್ಣ ಇಟರೇಷನ್ ತರ್ಕವನ್ನು ಸರಳಗೊಳಿಸಲು ಒಂದು ಪ್ರಬಲ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ.
function* generator1() {
yield 1;
yield 2;
}
function* generator2() {
yield* generator1(); // Delegate to generator1
yield 3;
yield 4;
}
const iterator = generator2();
for (const value of iterator) {
console.log(value); // Output: 1, 2, 3, 4
}
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳನ್ನು ಬಳಸುವುದರ ಪ್ರಯೋಜನಗಳು
- ಸುಧಾರಿತ ಓದುವಿಕೆ: ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ಮ್ಯಾನುಯಲ್ ಇಟರೇಟರ್ ಅನುಷ್ಠಾನಗಳಿಗೆ ಹೋಲಿಸಿದರೆ ಇಟರೇಟರ್ ಕೋಡ್ ಅನ್ನು ಹೆಚ್ಚು ಸಂಕ್ಷಿಪ್ತ ಮತ್ತು ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಸುಲಭವಾಗಿಸುತ್ತವೆ.
- ಸರಳೀಕೃತ ಅಸಿಂಕ್ರೋನಸ್ ಪ್ರೊಗ್ರಾಮಿಂಗ್: ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಹೆಚ್ಚು ಸಿಂಕ್ರೋನಸ್ ಶೈಲಿಯಲ್ಲಿ ಬರೆಯಲು ನಿಮಗೆ ಅನುಮತಿಸುವ ಮೂಲಕ ಅವು ಅಸಿಂಕ್ರೋನಸ್ ಕೋಡ್ ಅನ್ನು ಸುಗಮಗೊಳಿಸುತ್ತವೆ.
- ಮೆಮೊರಿ ದಕ್ಷತೆ: ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ಬೇಡಿಕೆಯ ಮೇಲೆ ಮೌಲ್ಯಗಳನ್ನು ಉತ್ಪಾದಿಸುತ್ತವೆ, ಇದು ದೊಡ್ಡ ಡೇಟಾಸೆಟ್ಗಳು ಅಥವಾ ಅನಂತ ಅನುಕ್ರಮಗಳಿಗೆ ವಿಶೇಷವಾಗಿ ಪ್ರಯೋಜನಕಾರಿಯಾಗಿದೆ. ಅವು ಸಂಪೂರ್ಣ ಡೇಟಾಸೆಟ್ ಅನ್ನು ಒಂದೇ ಬಾರಿಗೆ ಮೆಮೊರಿಗೆ ಲೋಡ್ ಮಾಡುವುದನ್ನು ತಪ್ಪಿಸುತ್ತವೆ.
- ಕೋಡ್ ಮರುಬಳಕೆ: ನಿಮ್ಮ ಅಪ್ಲಿಕೇಶನ್ನ ವಿವಿಧ ಭಾಗಗಳಲ್ಲಿ ಬಳಸಬಹುದಾದ ಮರುಬಳಕೆ ಮಾಡಬಹುದಾದ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳನ್ನು ನೀವು ರಚಿಸಬಹುದು.
- ಹೊಂದಿಕೊಳ್ಳುವಿಕೆ: ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ವಿವಿಧ ಡೇಟಾ ರಚನೆಗಳು ಮತ್ತು ಇಟರೇಷನ್ ಮಾದರಿಗಳನ್ನು ನಿರ್ವಹಿಸಬಲ್ಲ ಕಸ್ಟಮ್ ಇಟರೇಟರ್ಗಳನ್ನು ರಚಿಸಲು ಹೊಂದಿಕೊಳ್ಳುವ ಮಾರ್ಗವನ್ನು ಒದಗಿಸುತ್ತವೆ.
ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳನ್ನು ಬಳಸಲು ಉತ್ತಮ ಅಭ್ಯಾಸಗಳು
- ವಿವರಣಾತ್ಮಕ ಹೆಸರುಗಳನ್ನು ಬಳಸಿ: ಕೋಡ್ ಓದುವಿಕೆಯನ್ನು ಸುಧಾರಿಸಲು ನಿಮ್ಮ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ಮತ್ತು ವೇರಿಯಬಲ್ಗಳಿಗೆ ಅರ್ಥಪೂರ್ಣ ಹೆಸರುಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ.
- ದೋಷಗಳನ್ನು ಸರಿಯಾಗಿ ನಿರ್ವಹಿಸಿ: ಅನಿರೀಕ್ಷಿತ ನಡವಳಿಕೆಯನ್ನು ತಡೆಗಟ್ಟಲು ನಿಮ್ಮ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳಲ್ಲಿ ದೋಷ ನಿರ್ವಹಣೆಯನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಿ.
- ಅನಂತ ಅನುಕ್ರಮಗಳನ್ನು ಮಿತಿಗೊಳಿಸಿ: ಅನಂತ ಅನುಕ್ರಮಗಳೊಂದಿಗೆ ಕೆಲಸ ಮಾಡುವಾಗ, ಅನಂತ ಲೂಪ್ಗಳು ಅಥವಾ ಮೆಮೊರಿ ಖಾಲಿಯಾಗುವುದನ್ನು ತಪ್ಪಿಸಲು ಹಿಂಪಡೆಯುವ ಮೌಲ್ಯಗಳ ಸಂಖ್ಯೆಯನ್ನು ಮಿತಿಗೊಳಿಸುವ ಯಾಂತ್ರಿಕತೆಯನ್ನು ಹೊಂದಿರುವಿರಾ ಎಂದು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ.
- ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಪರಿಗಣಿಸಿ: ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ಸಾಮಾನ್ಯವಾಗಿ ದಕ್ಷವಾಗಿದ್ದರೂ, ವಿಶೇಷವಾಗಿ ಗಣನಾತ್ಮಕವಾಗಿ ತೀವ್ರವಾದ ಕಾರ್ಯಾಚರಣೆಗಳೊಂದಿಗೆ ವ್ಯವಹರಿಸುವಾಗ ಕಾರ್ಯಕ್ಷಮತೆಯ ಪರಿಣಾಮಗಳ ಬಗ್ಗೆ ಗಮನವಿರಲಿ.
- ನಿಮ್ಮ ಕೋಡ್ ಅನ್ನು ದಾಖಲಿಸಿ: ನಿಮ್ಮ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳನ್ನು ಹೇಗೆ ಬಳಸುವುದು ಎಂಬುದನ್ನು ಇತರ ಡೆವಲಪರ್ಗಳಿಗೆ ಅರ್ಥಮಾಡಿಕೊಳ್ಳಲು ಸಹಾಯ ಮಾಡಲು ಸ್ಪಷ್ಟ ಮತ್ತು ಸಂಕ್ಷಿಪ್ತ ದಾಖಲಾತಿಯನ್ನು ಒದಗಿಸಿ.
ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಆಚೆಗಿನ ಬಳಕೆಯ ಪ್ರಕರಣಗಳು
ಜನರೇಟರ್ಗಳು ಮತ್ತು ಇಟರೇಟರ್ಗಳ ಪರಿಕಲ್ಪನೆಯು ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅನ್ನು ಮೀರಿ ವಿಸ್ತರಿಸುತ್ತದೆ ಮತ್ತು ವಿವಿಧ ಪ್ರೊಗ್ರಾಮಿಂಗ್ ಭಾಷೆಗಳು ಮತ್ತು ಸನ್ನಿವೇಶಗಳಲ್ಲಿ ಅನ್ವಯಗಳನ್ನು ಕಂಡುಕೊಳ್ಳುತ್ತದೆ. ಉದಾಹರಣೆಗೆ:
- ಪೈಥಾನ್: ಪೈಥಾನ್
yieldಕೀವರ್ಡ್ ಬಳಸಿ ಜನರೇಟರ್ಗಳಿಗೆ ಅಂತರ್ನಿರ್ಮಿತ ಬೆಂಬಲವನ್ನು ಹೊಂದಿದೆ, ಇದು ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ಗೆ ಬಹಳ ಹೋಲುತ್ತದೆ. ಅವುಗಳನ್ನು ದಕ್ಷ ಡೇಟಾ ಸಂಸ್ಕರಣೆ ಮತ್ತು ಮೆಮೊರಿ ನಿರ್ವಹಣೆಗಾಗಿ ವ್ಯಾಪಕವಾಗಿ ಬಳಸಲಾಗುತ್ತದೆ. - C#: C# ಕಸ್ಟಮ್ ಕಲೆಕ್ಷನ್ ಇಟರೇಷನ್ ಅನ್ನು ಕಾರ್ಯಗತಗೊಳಿಸಲು ಇಟರೇಟರ್ಗಳು ಮತ್ತು
yield returnಸ್ಟೇಟ್ಮೆಂಟ್ ಅನ್ನು ಬಳಸುತ್ತದೆ. - ಡೇಟಾ ಸ್ಟ್ರೀಮಿಂಗ್: ಡೇಟಾ ಪ್ರೊಸೆಸಿಂಗ್ ಪೈಪ್ಲೈನ್ಗಳಲ್ಲಿ, ದೊಡ್ಡ ಡೇಟಾ ಸ್ಟ್ರೀಮ್ಗಳನ್ನು ಭಾಗಗಳಲ್ಲಿ ಪ್ರೊಸೆಸ್ ಮಾಡಲು ಜನರೇಟರ್ಗಳನ್ನು ಬಳಸಬಹುದು, ಇದು ದಕ್ಷತೆಯನ್ನು ಸುಧಾರಿಸುತ್ತದೆ ಮತ್ತು ಮೆಮೊರಿ ಬಳಕೆಯನ್ನು ಕಡಿಮೆ ಮಾಡುತ್ತದೆ. ಸಂವೇದಕಗಳು, ಹಣಕಾಸು ಮಾರುಕಟ್ಟೆಗಳು, ಅಥವಾ ಸಾಮಾಜಿಕ ಮಾಧ್ಯಮಗಳಿಂದ ನೈಜ-ಸಮಯದ ಡೇಟಾದೊಂದಿಗೆ ವ್ಯವಹರಿಸುವಾಗ ಇದು ವಿಶೇಷವಾಗಿ ಮುಖ್ಯವಾಗಿದೆ.
- ಗೇಮ್ ಡೆವಲಪ್ಮೆಂಟ್: ಭೂಪ್ರದೇಶ ಉತ್ಪಾದನೆ ಅಥವಾ ಆನಿಮೇಷನ್ ಅನುಕ್ರಮಗಳಂತಹ ಕಾರ್ಯವಿಧಾನದ ವಿಷಯವನ್ನು ರಚಿಸಲು ಜನರೇಟರ್ಗಳನ್ನು ಬಳಸಬಹುದು, ಸಂಪೂರ್ಣ ವಿಷಯವನ್ನು ಮೊದಲೇ ಲೆಕ್ಕಾಚಾರ ಮಾಡಿ ಮೆಮೊರಿಯಲ್ಲಿ ಸಂಗ್ರಹಿಸದೆ.
ತೀರ್ಮಾನ
ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ಇಟರೇಟರ್ಗಳನ್ನು ರಚಿಸಲು ಮತ್ತು ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಾಚರಣೆಗಳನ್ನು ಹೆಚ್ಚು ಸೊಗಸಾದ ಮತ್ತು ದಕ್ಷ ರೀತಿಯಲ್ಲಿ ನಿರ್ವಹಿಸಲು ಒಂದು ಪ್ರಬಲ ಸಾಧನವಾಗಿದೆ. ಇಟರೇಟರ್ ಪ್ರೊಟೊಕಾಲ್ ಅನ್ನು ಅರ್ಥಮಾಡಿಕೊಳ್ಳುವ ಮೂಲಕ ಮತ್ತು yield ಕೀವರ್ಡ್ನಲ್ಲಿ ಪಾಂಡಿತ್ಯವನ್ನು ಗಳಿಸುವ ಮೂಲಕ, ಹೆಚ್ಚು ಓದಬಲ್ಲ, ನಿರ್ವಹಿಸಬಲ್ಲ ಮತ್ತು ಕಾರ್ಯಕ್ಷಮತೆಯ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ಮಿಸಲು ನೀವು ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳನ್ನು ಬಳಸಿಕೊಳ್ಳಬಹುದು. ಸಂಖ್ಯೆಗಳ ಅನುಕ್ರಮಗಳನ್ನು ರಚಿಸುವುದರಿಂದ ಹಿಡಿದು ಸಂಕೀರ್ಣ ಡೇಟಾ ರಚನೆಗಳನ್ನು ಕ್ರಮಿಸುವುದು ಮತ್ತು ಅಸಿಂಕ್ರೋನಸ್ ಕಾರ್ಯಗಳನ್ನು ನಿರ್ವಹಿಸುವವರೆಗೆ, ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳು ವ್ಯಾಪಕ ಶ್ರೇಣಿಯ ಪ್ರೊಗ್ರಾಮಿಂಗ್ ಸವಾಲುಗಳಿಗೆ ಬಹುಮುಖ ಪರಿಹಾರವನ್ನು ನೀಡುತ್ತವೆ. ನಿಮ್ಮ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಅಭಿವೃದ್ಧಿ ಕೆಲಸದ ಹರಿವಿನಲ್ಲಿ ಹೊಸ ಸಾಧ್ಯತೆಗಳನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ಜನರೇಟರ್ ಫಂಕ್ಷನ್ಗಳನ್ನು ಅಳವಡಿಸಿಕೊಳ್ಳಿ.