একটি iterator হলো যা কিছুতে for...of আর spread operator কাজ করায় — যেকোনো object implement করতে পারে এমন একটি protocol। একটি generator একটি বিশেষ ধরনের function যা স্বয়ংক্রিয়ভাবে একটি iterator বানায়, আর নিজের execution থামাতে পারে।
Array, string, Map, আর Set সবই iterable — এগুলো Symbol.iterator implement করে, একটি method যা একবারে একটা মান তৈরি করা একটি next() method সহ একটি object return করে।
const numbers = [10, 20, 30]
const iterator = numbers[Symbol.iterator]()
iterator.next() // { value: 10, done: false }
iterator.next() // { value: 20, done: false }
iterator.next() // { value: 30, done: false }
iterator.next() // { value: undefined, done: true }for...of আসলে পেছনে বারবার next() call করা, done true হলে থামে।
function* দিয়ে চিহ্নিত একটি generator প্রতিটি yield-এ থামে আর পরের বার call হলে ঠিক যেখানে ছেড়েছিল সেখান থেকে resume করে।
function* countUpTo(max) {
let count = 1
while (count <= max) {
yield count
count++
}
}
const counter = countUpTo(3)
counter.next() // { value: 1, done: false }
counter.next() // { value: 2, done: false }
counter.next() // { value: 3, done: false }
counter.next() // { value: undefined, done: true }একটি generator স্বয়ংক্রিয়ভাবে iterator protocol implement করে বলে, এটা সরাসরি for...of আর spread operator-এর সাথে কাজ করে।
for (const n of countUpTo(3)) {
console.log(n) // 1, 2, 3
}
[...countUpTo(3)] // [1, 2, 3]একটি generator শুধু চাওয়া হলে পরের মান হিসাব করে বলে, এটা একবারে বানানোর জন্য অনেক বড় — বা infinite — একটি sequence represent করতে পারে।
function* infiniteIds() {
let id = 1
while (true) {
yield id++
}
}
const ids = infiniteIds()
ids.next().value // 1
ids.next().value // 2
// আসলে কখনো একটি infinite array বানায় না — শুধু একবারে একটা মান তৈরি করেasync/await-এর সাথে সংযোগ
একটি generator-এর pause-and-resume behavior conceptually async/await-এর ভিত্তির mechanism-ও — দুটোই একটি function-কে execution-এর মাঝে থামতে আর অন্য কিছু block না করে পরে চালিয়ে যেতে দেয়।