Generators, một loại hàm đặc biệt trong JavaScript, cho phép bạn tạm dừng và tiếp tục thực thi mã theo ý muốn. Hãy cùng tìm hiểu cách Generators có thể tối ưu hóa code và mở ra những khả năng mới cho lập trình JavaScript của bạn.
Generators là gì?
Nói một cách đơn giản, Generators là những hàm có khả năng "tạm dừng" và "tiếp tục" quá trình thực thi. Không giống như các hàm thông thường chạy từ đầu đến cuối, Generators mang đến sự kiểm soát linh hoạt hơn cho lập trình viên nhờ cú pháp function* và từ khóa yield.
VD:
function* myFirstGenerator() { yield "Hello 🌟"; yield "Generators are awesome!"; yield "Goodbye 👋";
} // Let's use it!
const gen = myFirstGenerator(); console.log(gen.next()); // { value: 'Hello 🌟', done: false }
console.log(gen.next()); // { value: 'Generators are awesome!', done: false }
console.log(gen.next()); // { value: 'Goodbye 👋', done: false }
console.log(gen.next()); // { value: undefined, done: true }
Giải thích:
- Từ khóa yield đóng vai trò như điểm tạm dừng trong hàm của bạn.
- Mỗi lần gọi gen.next() sẽ di chuyển hàm tới hàm yield tiếp theo.
- Khi không còn câu lệnh yield nào nữa, trình tạo sẽ trả về
{ done: true }
.
Các trường hợp sử dụng Generators trong thực tế
1. Bộ tạo chuỗi vô hạn
Một trong những trường hợp sử dụng phổ biến là tạo chuỗi số vô hạn mà không gây tràn bộ nhớ.
VD:
function* infiniteNumbers() { let num = 1; while (true) { yield num++; }
} const numbers = infiniteNumbers(); console.log(numbers.next().value); // 1
console.log(numbers.next().value); // 2
console.log(numbers.next().value); // 3
// ... and so on
2. Lặp lại có kiểm soát để lấy dữ liệu
Ngoài ra, Generators còn hữu ích trong việc kiểm soát việc lặp lại để lấy dữ liệu.
VD:
function* fetchInChunks(data) { for (let i = 0; i < data.length; i += 2) { yield data.slice(i, i + 2); }
} const chunks = fetchInChunks([1, 2, 3, 4, 5, 6, 7, 8]); console.log(chunks.next().value); // [1, 2]
console.log(chunks.next().value); // [3, 4]
console.log(chunks.next().value); // [5, 6]
3. Hữu ích với trình tạo ủy quyền
Một tính năng thú vị khác của Generators là khả năng gọi các Generators khác bằng từ khóa yield*. Điều này cho phép kết hợp nhiều Generators để tạo ra các luồng xử lý phức tạp hơn. Ví dụ dưới đây minh họa cách Generators lồng nhau hoạt động.
function* innerGenerator() { yield "I’m the inner generator 🎯";
} function* outerGenerator() { yield "I’m the outer generator 🌟"; yield* innerGenerator(); yield "Back to the outer generator 👋";
} const gen = outerGenerator(); for (const value of gen) { console.log(value);
}
Output:
I’m the outer generator 🌟 I’m the inner generator 🎯 Back to the outer generator 👋
Vậy tại sao nên sử dụng Generators?
- Thứ nhất, Generators hỗ trợ lazy evaluation, tức là chỉ tạo giá trị khi cần thiết.
- Thứ hai, Generators giúp cải thiện hiệu suất bằng cách tránh tính toán tất cả kết quả cùng một lúc.
- Cuối cùng, Generators có thể kết hợp với async/await để viết code asynchronous gọn gàng và dễ đọc hơn.
Tóm lại, Generators là một công cụ mạnh mẽ trong JavaScript, tuy ban đầu có vẻ khó hiểu nhưng với việc luyện tập, bạn sẽ nhanh chóng thành thạo. Hãy bắt đầu với những ví dụ đơn giản, khám phá các khả năng của Generators, và bạn sẽ sớm sử dụng chúng như một chuyên gia.