Чтение онлайн

на главную - закладки

Жанры

JavaScript. Подробное руководство, 6-е издание
Шрифт:

Тот факт, что генераторы имеют метод

next,
который может возбуждать исключение
StopIteration
, явственно говорит о том, что они являются итераторами. [22] В действительности они являются итерируемыми итераторами, т. е. они могут использоваться в циклах
for/in
. Следующий пример демонстрирует, насколько просто создавать функции-генераторы и выполнять итерации по значениям, которые они возвращают с помощью инструкции
yield
:

22

Генераторы

иногда называют «итераторами-генераторами», чтобы отличить их от создающих их функций-генераторов. В этой главе вместо термина «итераторы-генераторы» мы будем использовать термин «генераторы». В других источниках вы можете встретить термин «генератор», обозначающий одновременно и функции-генераторы, и итераторы-генераторы.

// Определение функции-генератора для выполнения итераций

// по целым числам в определенном диапазоне

function range(min, max) {

for(let і = Math.ceil(min); і <= max; i++) yield i;

}

// Вызвать функцию-генератор, чтобы получить генератор, и выполнить итерации по нему,

fог(let n in range(3.8)) console.log(n); // Выведет числа от 3 до 8.

Функции-генераторы могут никогда не завершаться. Каноническим примером использования генераторов является воспроизведение последовательности чисел Фибоначчи:

// Функция-генератор, которая воспроизводит последовательность чисел Фибоначчи

function fibonacci {

let х = 0, у = 1;

while(true) {

yield у;

[х,у] = [у,х+у];

}

}

// Вызвать функцию-генератор, чтобы получить генератор,

f = fibonacci;

// Использовать генератор как итератор, вывести первые 10 чисел Фибоначчи,

for(let і = 0; і < 10; і++) console.log(f.next);

Обратите внимание, что функция-генератор

fibonacci
никогда не завершится. По этой причине создаваемый ею генератор никогда не возбудит исключение
StopIteration
. Поэтому, вместо того чтобы использовать его как итерируемый объект в цикле
for/in
и попасть в бесконечный цикл, мы используем его как итератор и явно вызываем его метод
next
десять раз. После того как фрагмент выше будет выполнен, генератор f по-прежнему будет хранить информацию о состоянии функции-генератора. Если в программе не требуется далее
хранить эту информацию, ее можно освободить вызовом метода
close
объекта f:

f.close;

При вызове метода

close
генератора производится завершение связанной с ним функции-генератора, как если бы она выполнила инструкцию
return
в той точке, где ее выполнение было приостановлено. Если это произошло в блоке
try
, автоматически будет выполнен блок
finally
перед тем, как
close
вернет управление. Метод
close
никогда не возвращает значение, но если блок
finally
возбудит исключение, оно продолжит свое распространение из вызова
close.

Генераторы часто бывает удобно использовать для последовательной обработки данных - элементов списка, строк текста, лексем в лексическом анализаторе и т.д. Генераторы можно объединять в цепочки, подобно конвейеру команд в Unix. Самое интересное в этом подходе заключается в том, что он следует принципу отложенных вычислений: значения «извлекаются» из генератора (или из конвейера генераторов) по мере необходимости, а не все сразу. Эту особенность демонстрирует пример 11.1.

Пример 11.1. Конвейер генераторов

// Генератор, возвращающий строки текста по одной.

// Обратите внимание, что здесь не используется метод s.split, потому что

// он обрабатывает текст целиком, создает массив, тогда как нам необходимо

// реализовать отложенную обработку,

function eachline(s) {

let р;

while((p = s.indexOf( \n')) != -1) {

yield s. substrings, p);

s = s.substring(p+1);

}

if (s.length > 0) yield s;

}

// Функция-генератор, возвращающая f(x) для каждого элемента х итерируемого объекта і

function map(і. f) {

fоr(let x in i) yield f(x);

}

// Функция-генератор, возвращающая элементы і, для которых f(x) возвращает true

function select(i, f) {

for(let x in i) {

if (f(x)) yield x;

}

Поделиться:
Популярные книги

Место под солнцем

Гавриил Одинокий
Старинная литература:
прочая старинная литература
6.00
рейтинг книги
Место под солнцем

Российская империя в сравнительной перспективе

Коллектив авторов
Научно-образовательная:
история
политика
5.00
рейтинг книги
Российская империя в сравнительной перспективе

Цикл "Идеальный мир для Лекаря". Компиляция. Книги 1-30

Сапфир Олег
Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Цикл Идеальный мир для Лекаря. Компиляция. Книги 1-30

Неучтенный. Дилогия

Муравьёв Константин Николаевич
Неучтенный
Фантастика:
боевая фантастика
попаданцы
7.98
рейтинг книги
Неучтенный. Дилогия

Каратила

Поповский Андрей Владимирович
Детективы:
боевики
6.50
рейтинг книги
Каратила

Лекарь Империи 2

Карелин Сергей Витальевич
2. Лекарь Империи
Фантастика:
городское фэнтези
аниме
дорама
фэнтези
попаданцы
5.80
рейтинг книги
Лекарь Империи 2

Лекции профессора Московской Духовной Академии А. И. Осипова

Осипов Алексей Ильич
Религия и эзотерика:
религия
5.00
рейтинг книги
Лекции профессора Московской Духовной Академии А. И. Осипова

Точка Бифуркации

Смит Дейлор
1. ТБ
Фантастика:
боевая фантастика
7.43
рейтинг книги
Точка Бифуркации

Рассказы старых переплетов

Белоусов Роман Сергеевич
Документальная литература:
биографии и мемуары
прочая документальная литература
5.00
рейтинг книги
Рассказы старых переплетов

Информационные технологии в СССР. Создатели советской вычислительной техники

Малиновский Борис Николаевич
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Информационные технологии в СССР. Создатели советской вычислительной техники

Сын Петра. Том 1. Бесенок

Ланцов Михаил Алексеевич
1. Сын Петра
Фантастика:
попаданцы
альтернативная история
6.80
рейтинг книги
Сын Петра. Том 1. Бесенок

Восточный массаж

Ханников Александр Александрович
Дом и Семья:
здоровье и красота
7.00
рейтинг книги
Восточный массаж

Эпоха Опустошителя. Том V

Павлов Вел
5. Вечное Ристалище
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Эпоха Опустошителя. Том V

Газлайтер. Том 9

Володин Григорий Григорьевич
9. История Телепата
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Газлайтер. Том 9