Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

Function* (Generator Function) ใน JavaScript คืออะไร

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)