2.1 Синтаксис генераторов
Генераторы в JavaScript представляют собой специальные функции, которые позволяют управлять выполнением кода. Они могут приостанавливать свое выполнение и возобновлять его позже, что делает их мощным инструментом для работы с асинхронным кодом, итераторами и другими сложными задачами.
Генераторы определяются с помощью функции function* (обратите внимание на звездочку). Внутри генератора используется оператор yield для приостановки выполнения и возврата значения.
Объявление генератора:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
Создание объекта генератора
Вызов генератора не выполняет его тело сразу. Вместо этого он возвращает объект генератора, который можно использовать для итерации по значениям:
const gen = generatorFunction();
2.2 Использование генераторов
Метод next()
Метод next() используется для возобновления выполнения генератора до следующего оператора yield. Он возвращает объект с двумя свойствами:
value: значение, переданное операторомyielddone: логическое значение, указывающее, завершен ли генератор (true) или нет (false)
Пример использования метода next():
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
Итерация по генератору
Генераторы могут использоваться с циклом for...of для итерации по значениям.
Пример итерации по генератору:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
for (const value of gen) {
console.log(value);
}
// Выведет: 1
// Выведет: 2
// Выведет: 3
Пример возврата значений
Генераторы могут возвращать значение с помощью оператора return:
function* generatorFunction() {
yield 1;
yield 2;
return 3;
yield 4; // Этот yield никогда не будет выполнен
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: true }
console.log(gen.next()); // { value: undefined, done: true }
2.3 Сложное использование генераторов
Взаимодействие с генератором
Метод next() может принимать аргумент, который передается в генератор и может использоваться внутри него.
Пример передачи значений в генератор:
function* generatorFunction() {
const value1 = yield 1;
const value2 = yield value1 + 2;
yield value2 + 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next(10)); // { value: 12, done: false }
console.log(gen.next(20)); // { value: 23, done: false }
console.log(gen.next()); // { value: undefined, done: true }
Обработка ошибок
Генераторы позволяют обрабатывать ошибки с помощью блока try...catch.
Пример обработки ошибок:
function* generatorFunction() {
try {
yield 1;
yield 2;
} catch (error) {
console.log('Error caught:', error);
}
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.throw(new Error('Something went wrong'))); // Error caught: Error: Something went wrong
// { value: undefined, done: true }
Пример генератора для создания бесконечной последовательности
Генераторы могут использоваться для создания бесконечных последовательностей значений:
function* infiniteSequence() {
let i = 0;
while (true) {
yield i++;
}
}
const gen = infiniteSequence();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
// и так далее
2.4 Примеры практического использования
Пример 1: Генератор для итерации по объекту
function* objectEntries(obj) {
const keys = Object.keys(obj);
for (const key of keys) {
yield [key, obj[key]];
}
}
const obj = { a: 1, b: 2, c: 3 };
const gen = objectEntries(obj);
for (const [key, value] of gen) {
console.log(`${key}: ${value}`);
}
// Выведет:
// a: 1
// b: 2
// c: 3
Пример 2: Генератор для реализации простого итератора
const myIterable = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
};
for (const value of myIterable) {
console.log(value);
}
// Выведет: 1
// Выведет: 2
// Выведет: 3
Генераторы в JavaScript представляют собой мощный инструмент для управления выполнением кода, создания итераторов и работы с асинхронными операциями. Понимание синтаксиса и использования генераторов помогает создавать более гибкий и читаемый код, особенно при работе с последовательностями данных и асинхронными задачами.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ