Generator Functions cho phép tạm dừng thực thi function và tiếp tục sau. Quản lý flow control, dễ dàng cancel async operations vì có thể pause bất kỳ lúc nào.
Cú pháp
Thêm dấu * sau function:
function *myGenerator() {}
// hoặc
function* myGenerator() {}
// hoặc
function*myGenerator() {}
Ví dụ cơ bản
<html>
<body>
<script>
function* display() {
var num = 1;
while (num < 5) {
yield num++; // Tạm dừng, trả về giá trị
}
}
var myGenerator = display(); // Trả về Generator object (iterator)
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>
Generator Object Methods
| Method | Mô tả |
|---|---|
next(value) | Tiếp tục thực thi, truyền value vào yield expression. Trả về {value, done}. |
return(value) | Kết thúc generator sớm, trả về {value, done: true}. |
throw(error) | Ném error vào generator tại yield position. |
Yield Expression
yield value: Tạm dừng, trảvalue.yield* otherGenerator: Delegate to another generator (yield delegation).const input = yield value: Nhận giá trị từnext(input).
Ví dụ thực tế: Infinite Sequence / Lazy Evaluation
// Infinite counter
function* counter() {
let i = 0;
while (true) yield i++;
}
const gen = counter();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
// ... không bao giờ hết
// Fibonacci generator
function* fibonacci() {
let [prev, curr] = [0, 1];
while (true) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
// Async generator (ES2018) - cho async iteration
async function* fetchPages(url) {
let nextUrl = url;
while (nextUrl) {
const response = await fetch(nextUrl);
const data = await response.json();
yield data.items;
nextUrl = data.nextPage;
}
}
// Usage: for await (const items of fetchPages('/api/items')) { ... }
Use Cases
- Lazy evaluation (xử lý dataset lớn, stream).
- State machine, finite automata.
- Async flow control (co-routine pattern).
- Infinite sequences.
- Custom iterators cho object.
Iterable Protocol
Generator tự động implement Symbol.iterator → dùng được for...of, spread ..., Array.from().
function* range(start, end) {
for (let i = start; i < end; i++) yield i;
}
console.log([...range(1, 5)]); // [1, 2, 3, 4]
for (const n of range(1, 5)) console.log(n);