Generator Function (ประกาศด้วย function*) เป็นฟังก์ชันพิเศษที่สามารถหยุดทำงานชั่วคราว (pause) และกลับมาทำงานต่อ (resume) ได้ คืนค่า Generator object ที่ควบคุมการทำงานได้
ไวยากรณ์ (Syntax)
function *myGenerator() {} // หรือ
function* myGenerator() {} // หรือ
function*myGenerator() {}
ตัวอย่างพื้นฐาน
<html>
<body>
<script>
function* display() {
var num = 1;
while (num < 5) {
yield num++;
}
}
var myGenerator = display();
document.write(myGenerator.next().value); // 1
document.write("<br>" + myGenerator.next().value); // 2
document.write("<br>" + myGenerator.next().value); // 3
document.write("<br>" + myGenerator.next().value); // 4
document.write("<br>" + myGenerator.next().value); // undefined (done: true)
</script>
</body>
</html>
คีย์เวิร์ด yield
yield value- หยุดการทำงานและส่งค่าvalueกลับไปyield*- ยกเลิกการ delegate ให้ generator อื่น (delegation)
เมธอดของ Generator Object
| เมธอด | คำอธิบาย |
|---|---|
next() | ดำเนินการต่อจนถึง yield ถัดไป คืน {value, done} |
return(value) | จบการทำงานทันที คืน {value, done: true} |
throw(error) | โยน error เข้าไปใน generator |
ตัวอย่างขั้นสูง
1. Infinite Sequence
function* idGenerator() {
let id = 1;
while (true) {
yield id++;
}
}
const gen = idGenerator();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
// ไม่มีที่สิ้นสุด
2. ใช้กับ for...of loop
function* range(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
for (const num of range(1, 5)) {
console.log(num); // 1, 2, 3, 4, 5
}
3. Async Flow Control
function* fetchUserData(userId) {
const user = yield fetch(`/api/users/${userId}`).then(r => r.json());
const posts = yield fetch(`/api/users/${userId}/posts`).then(r => r.json());
return { user, posts };
}
// Runner function
function run(generator) {
const iterator = generator();
function handle(result) {
if (result.done) return result.value;
return Promise.resolve(result.value).then(
val => handle(iterator.next(val)),
err => handle(iterator.throw(err))
);
}
return handle(iterator.next());
}
4. ส่งค่าเข้าไปใน Generator
function* logger() {
while (true) {
const message = yield;
console.log('Log:', message);
}
}
const log = logger();
log.next(); // เริ่มต้น (ไปถึง yield แรก)
log.next('Hello'); // Log: Hello
log.next('World'); // Log: World
กรณีใช้งานจริง (Use Cases)
- การจัดการ Async flow (ก่อน async/await)
- Infinite sequences / Lazy evaluation
- Custom iterators
- State machines
- Middleware pattern (Redux-saga)