JavaScript. Подробное руководство, 6-е издание, стр. 153
Тот факт, что генераторы имеют метод
<b>next(),</b><b>StopIteration</b><b>for/in</b><b>yield</b><b>// Определение функции-генератора для выполнения итераций</b><b>// по целым числам в определенном диапазоне</b><b>function range(min, max) {</b><b> for(let і = Math.ceil(min); і <= max; i++) yield i;</b><b>}</b><b>// Вызвать функцию-генератор, чтобы получить генератор, и выполнить итерации по нему, </b><b>fог(let n in range(3.8)) console.log(n); // Выведет числа от 3 до 8.</b>Функции-генераторы могут никогда не завершаться. Каноническим примером использования генераторов является воспроизведение последовательности чисел Фибоначчи:
<b>// Функция-генератор, которая воспроизводит последовательность чисел Фибоначчи</b><b>function fibonacci() {</b><b> let х = 0, у = 1;</b><b> while(true) {</b><b> yield у;</b><b> [х,у] = [у,х+у];</b><b> }</b><b>}</b><b>// Вызвать функцию-генератор, чтобы получить генератор,</b><b>f = fibonacci();</b><b>// Использовать генератор как итератор, вывести первые 10 чисел Фибоначчи,</b><b>for(let і = 0; і < 10; і++) console.log(f.next());</b>Обратите внимание, что функция-генератор
<b>fibonacci()</b><b>StopIteration</b><b>for/in</b><b>next()</b><b>close()</b><b>f.close();</b>При вызове метода
<b>close()</b><b>return</b><b>try</b><b>finally</b><b>close()</b><b>close()</b><b>finally </b><b>close().</b>Генераторы часто бывает удобно использовать для последовательной обработки данных - элементов списка, строк текста, лексем в лексическом анализаторе и т.д. Генераторы можно объединять в цепочки, подобно конвейеру команд в Unix. Самое интересное в этом подходе заключается в том, что он следует принципу отложенных вычислений: значения «извлекаются» из генератора (или из конвейера генераторов) по мере необходимости, а не все сразу. Эту особенность демонстрирует пример 11.1.
Пример 11.1. Конвейер генераторов
<b>// Генератор, возвращающий строки текста по одной.</b><b>// Обратите внимание, что здесь не используется метод s.split(), потому что </b><b>// он обрабатывает текст целиком, создает массив, тогда как нам необходимо </b><b>// реализовать отложенную обработку, </b><b>function eachline(s) {</b><b> let р;</b><b> while((p = s.indexOf( \n')) != -1) {</b><b> yield s. substrings, p);</b><b> s = s.substring(p+1);</b><b> }</b><b> if (s.length > 0) yield s;</b><b>}</b><b>// Функция-генератор, возвращающая f(x) для каждого элемента х итерируемого объекта і</b><b>function map(і. f) {</b><b> fоr(let x in i) yield f(x);</b><b>}</b><b>// Функция-генератор, возвращающая элементы і, для которых f(x) возвращает true</b><b>function select(i, f) {</b><b> for(let x in i) {</b><b> if (f(x)) yield x;</b><b> }</b><b>}</b><b>// Обрабатываемый текст</b><b>let text = " «comment \n \n hello \nworld\n quit \n unreached \n";</b>