HTML / CSSJavaScriptNode jsПаттерны проектированияПрактические

Генераторы

Генераторы - это специальный тип функции, который работает как фабрика итераторов. Функция становится генератором, если содержит один или более yield операторов и использует function* синтаксис.

Способы обьъявления

1function* generator(){
2function *generator(){}
3function * generator(){}
4const myGenerator = function *(){}
5
6class MyClass{
7 *generator(){}
8}
9
10const MyObj = {
11 *generator(){
12}
❗️Важно

Когда мы вызываем функцию-генератор, она возвращает нам объект-итератор.

Отличие от обычных функций

function

  • Обычные функции возвращают только одно-единственное значение (или ничего).

function*

  • Генераторы могут порождать (yield) множество значений одно за другим, по мере необходимости.
  • Генераторы Отлично работают с перебираемыми объектами и позволяют легко создавать потоки данных.
  • Генераторы могут приостанавливать своё выполнение, возвращать промежуточный результат и далее возобновлять его позже, в произвольный момент времени.
1function* simpleGenerator() {
2 yield "simple";
3 yield "generator";
4}
5
6const it = simpleGenerator();
7console.log(it.next()); // {value: 'simple, done: false}
8console.log(it.next()); // {value: 'generator, done: false}
9console.log(it.next()); // {value: undefined, done: true}

yield - приостанавливает выполнение функции и возвращает некое значение.

Итераторы и генераторы могут обмениваться данными в двух направлениях. А именно, генераторы, с помощью ключевого слова yield, могут возвращать значения итераторам, однако и итераторы могут отправлять данные генераторам, используя метод iterator.next('someValue')

1function* favBeer() {
2
3 const reply = yield "What is your favorite type of beer?";
4 console.log(reply);
5
6 if (reply !== "ipa") return "No soup for you!";
7
8 return "OK, soup.";
9}
10
11const it = favBeer();
12const q = it.next().value; // Итератор задаёт вопрос
13console.log(q);
14const a = it.next("lager").value; // Получен ответ на вопрос
15console.log(a);
16
17// What is your favorite beer?
18// lager
19// No soup for you!

Замена RangeIterator из лекции про итераторы на генератор createRangeGenerator

1function* createRangeGenerator(start, stop) {
2 for (var i = start; i <= stop; i++) {
3 yield i;
4 }
5}
6
7const range = createRangeGenerator(1, 3);
8
9console.log(range.next().value); // 1
10console.log(range.next().value); // 2
11console.log(range.next().value); // 3
12console.log(range.next().done); // true

Практика 👨‍💻👨‍💻

Задание 1

  • создать createСalendarGenerator

Задание 2

class MonthIterator

Воспользовавшись заданием из практики CalendarIterator переделать CalendarIterator так что бы он возвращал MonthIterator значением итератора

создать MonthIterator

Приватные поля:

  • name
  • days

Публичные поля:

  • next
  • toString

MonthIterator Должен итерировать дни месяца учитывая, что каждый месяц имеет не равное количество дней.

1class CalendarIterator{}
2
3const calendar = new CalendarIterator(1, 2);
4console.log(calendar.next().value); // MonthIterator
5
6const month = calendar.next().value
7
8console.log(month.toString()) // name of month
9console.log(month.next().value) // 1
10console.log(month.next().value) // 2
11console.log(month.next().value) // 3

Почитать 📚

Hello