Главная » Хабрахабр » [Перевод] О генераторах в JavaScript ES6, и о том, почему изучать их необязательно

[Перевод] О генераторах в JavaScript ES6, и о том, почему изучать их необязательно

С ростом популярности конструкции async/await растёт и интерес к её внутренним механизмам. Порывшись в интернете, несложно выяснить, что в основе async/await лежат широко известные промисы, и генераторы, которые пользуются куда меньшей известностью и популярностью.

А именно, тут мы поговорим о том, как они работают, и о том, как они, совместно с промисами, используются в недрах конструкции async/await. Материал, перевод которого мы сегодня публикуем, посвящён генераторам. Кроме того, он отмечает, что он рассчитывает на то, что читатель немного разбирается в промисах.
Автор этой статьи говорит, что генераторы, ради их практического применения, осваивать необязательно.

Итераторы и генераторы

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

Примечательной возможностью итераторов является то, что они предоставляют средства для доступа к элементам коллекций по одному за раз, и при этом позволяют отслеживать идентификатор текущего элемента.

function makeIterator(array) : { done: true }; } };
} var it = makeIterator(["simple", "iterator"]); console.log(it.next()); // {value: 'simple, done: false}
console.log(it.next()); // {value: 'iterator, done: false}
console.log(it.next()); // {done: true}

Выше мы передаём функции makeIterator() небольшой массив, содержащий пару элементов, после чего проходимся по нему с помощью итератора, вызывая метод it.next(). Обратите внимание на комментарии, демонстрирующие получаемые с помощью итератора результаты.

Генераторы — это функции, которые работают как фабрики итераторов. Теперь поговорим о генераторах. Рассмотрим простой пример, а затем поговорим о двух механизмах, имеющих отношение к генераторам.

function* sample() { yield "simple"; yield "generator";
} var it = sample(); console.log(it.next()); // {value: 'simple, done: false}
console.log(it.next()); // {value: 'generator, done: false}
console.log(it.next()); // {value: undefined, done: true}

Обратите внимание на звёздочку в объявлении функции. Это указывает на то, что данная функция является генератором. Кроме того, взгляните на ключевое слово yield. Оно приостанавливает выполнение функции и возвращает некое значение. Собственно, эти две особенности и являются теми самыми двумя механизмами, о которых мы говорили выше:

  • Функция-генератор — это функция, объявленная с использованием звёздочки около ключевого слова function или около имени функции.
  • Итератор генератора создаётся, когда вызывают функцию-генератор.

В общем-то, вышеописанный пример демонстрирует работу фабричной функции, генерирующей итераторы.

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

function* favBeer() { const reply = yield "What is your favorite type of beer?"; console.log(reply); if (reply !== "ipa") return "No soup for you!"; return "OK, soup.";
} { const it = favBeer(); const q = it.next().value; // Итератор задаёт вопрос console.log(q); const a = it.next("lager").value; // Получен ответ на вопрос console.log(a);
} // What is your favorite beer?
// lager
// No soup for you! { const it = favBeer(); const q = it.next().value; // Итератор задаёт вопрос console.log(q); const a = it.next("ipa").value; // получен ответ на вопрос console.log(a);
} // What is your favorite been?
// ipa
// OK, soup.

Генераторы и промисы

Теперь мы можем поговорить о том, как генераторы и промисы формируют базу конструкции async/await. Представьте, что вместо того, чтобы возвращать, с помощью ключевого слова yield, некие значения, генератор возвращает промисы. При таком раскладе генератор можно обернуть в функцию, которая будет ожидать разрешения промиса и возвращать значение промиса генератору в методе .next(), как было показано в предыдущем примере. Существует популярная библиотека, co, которая выполняет именно такие действия. Выглядит это так:

co(function* doStuff(){ var result - yield someAsyncMethod(); var another = yield anotherAsyncFunction();
});

Итоги

По мнению автора этого материала JS-разработчикам нужно знать о том, как работают генераторы, лишь для того, чтобы понимать особенности внутреннего устройства конструкции async/await. А вот использовать их непосредственно в собственном коде не стоит. Генераторы вводят в JavaScript возможность приостанавливать выполнение функции и возвращаться к ней когда (и если) разработчик сочтёт это необходимым. До сих пор мы, работая с JS-функциями, ожидали, что они, будучи вызванными, просто выполняются от начала до конца. Возможность их приостанавливать — это уже что-то новое, но этот функционал удобно реализован в конструкции async/await.

Например, один из аргументов в пользу генераторов, сводится к тому, что знание того, как они работают, полезно для отладки кода с async/await, так как внутри этой конструкции скрываются генераторы. С этим мнением, конечно, можно и поспорить. Однако автор материала полагает, что это, всё же, нечто иное, нежели использование генераторов в собственном коде.

Может быть, вы знаете какие-то варианты их использования, которые оправдывают их непосредственное применение в коде JS-проектов? Уважаемые читатели! Что вы думаете о генераторах?

Царский промо-код для скидки в 10% на наши виртуальные сервера:


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

[Перевод] На чём прокалывается ИИ при генерации человеческих лиц

В 2014 году исследователь в области машинного обучения Ян Гудфеллоу выдвинул идею генеративных состязательных сетей или GAN. «Генеративность» состоит в том, что результатом их работы являются изображения, а не оценка ввода (типа «хот-дог или нет»), а «состязательность» — в том, ...

«Когда ты — главный редактор Rusbase»: новый подкаст о работе с контентом и карьере в технологических медиа

Это — подкаст с теми, кто пишет, редактирует, снимает фото, видео и руководит созданием контента. Сегодня мы подготовили для вас текстовую версию четвертого выпуска. Мы говорим о карьере, рабочих инсайтах, «кухне» и новых проектах издания. Его гость — Светлана Зыкова ...