Q47. What are iterators and generators in JavaScript?
ধারাবাহিক মান ধাপে ধাপে বের করা এবং function-কে থামানো চালানোর ES6 সুবিধা।
Iterator হলো এমন object যার next() method আছে, যা ধাপে ধাপে একটি মান ফেরত দেয়। আর generator হলো এমন function যা yield দিয়ে থামে ও পরে চলতে পারে — তাই লুপ লিখে মান তৈরির দরকার নেই, অথচ একবারে সব মান মেমোরিতে জমে না।
// Iterator — নিজে থেকে বানানো
const numbers = {
current: 1,
max: 4,
next() {
if (this.current <= this.max) {
return { value: this.current++, done: false };
}
return { value: undefined, done: true };
},
};
console.log(numbers.next()); // { value: 1, done: false }
console.log(numbers.next()); // { value: 2, done: false }
console.log(numbers.next()); // { value: 3, done: false }
console.log(numbers.next()); // { value: 4, done: false }
console.log(numbers.next()); // { value: undefined, done: true }ধাপে ধাপে — প্রতিবার next() ডাকলে value ও done ফেরত হয়। current যতক্ষণ max-এর চেয়ে ছোট, মান দেয় ও current এক বাড়ায়। শেষে done: true এলে বোঝা যায় মান শেষ।
Generator লিখলে এই next()-এর কাজ JavaScript নিজেই করে দেয়।
// Generator
function* numberGenerator(limit) {
for (let i = 1; i <= limit; i++) {
yield i;
}
}
const gen = numberGenerator(3);
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }ধাপে ধাপে — ফাংশনের শুরুতে * চিহ্ন থাকায় এটি generator। yield i চালু হলে তখনই function থেমে যায় এবং i ফেরত দেয়। পরে next() ডাকলে ঠিক যেখান থামে ছিল সেখান থেকেই চলতে শুরু করে।
// for...of স্বয়ংক্রিয়ভাবে iterator ব্যবহার করে
for (const value of numberGenerator(3)) {
console.log(value); // 1, 2, 3
}
// spread operator-ও ব্যবহার করা যায়
console.log([...numberGenerator(3)]); // [1, 2, 3]সবচেয়ে বড় সুবিধা হলো lazy evaluation — মান তৈরি হয় শুধু তখনই যখন চাওয়া হয়। বিশাল ডেটা হলে এটি memory ও সময় দুটোই বাঁচায়।
// ❌ অযথা পুরো array বানিয়ে ফেলা
function createLabels(numbers) {
const result = [];
for (let i = 0; i < numbers.length; i++) {
result.push("Label " + numbers[i]);
}
return result; // ১ কোটি মান হলে মেমোরি ভেঙে যাবে
}
// ✅ Generator — যা দরকার তাই ধীরে ধীরে বানায়
function* createLabels(numbers) {
for (let i = 0; i < numbers.length; i++) {
yield "Label " + numbers[i];
}
}
// ব্যবহার
for (const label of createLabels(bigArray)) {
console.log(label);
if (label === "Label 99") break; // চাইলে মাঝেই থামা যায়
}// ফাংশনের ফলত্র পাওয়া যায়
function* range(start, end) {
let current = start;
while (current < end) {
yield current;
current++;
}
}
const gen = range(1, 10);
console.log([...gen]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
const lazy = range(1, 1000000);
console.log(lazy.next().value); // 1 — বাকি নব্বই লাখ বানানো হয়নি// মান পাঠানো যায় — value ও return দুটোই
function* counter() {
const received = yield 1; // এখানে কিছু পাঠানো হবে
console.log("পেয়েছি:", received);
yield 2;
return "শেষ"; // done: true হলে value হিসেবে আসে
}
const gen = counter();
console.log(gen.next().value); // 1
console.log(gen.next(10).value); // 2 — আগে "পেয়েছি: 10" ছাপা হয়
console.log(gen.next().value); // "শেষ"
console.log(gen.next().done); // true// অসীম generator
function* naturals() {
let n = 1;
while (true) {
yield n++;
}
}
const nat = naturals();
console.log(nat.next().value); // 1
console.log(nat.next().value); // 2
// তখনও শেষ হয়নি — শেষ হবেই না// generator-এর দুই ধরনের return
function* example() {
try {
yield 1;
yield 2;
} finally {
console.log("cleanup চলল");
}
}
for (const value of example()) {
if (value === 1) break; // break করলেও finally চলে
}| বিষয় | Iterator | Generator |
|---|---|---|
| কী | next() সহ object | function* দিয়ে তৈরি function |
| তৈরি করে | নিজে object বানাতে হয় | function* লিখলেই হয় |
| উদ্দেশ্য | ধাপে ধাপে মান দেওয়া | lazy ও থামানো চালানো ফাংশন |
| মেমোরি | সাধারণত সব মান থাকে | মান ধরে রাখে না |
| উদাহরণ | Symbol.iterator | function* ids() |
for...of, spread operator, Map, Set, Promise.all — প্রায় সবই ভেতরে iterator protocol ব্যবহার করে, তাই যেকোনো generator-কে এগুলোতে সরাসরি দেওয়া যায়। তবে generator একবার চললে পুনরায় চালানো যায় না; নতুন করে চালাতে ফাংশনটি আবার ডাকতে হয়।