Node.js Generators и сравнить с обратными вызовами
В этом уроке мы узнаем о Generators и их различия с обратными вызовами
Что такое генераторы?
Generatorстали довольно известными в Node.js в последнее время, и это, вероятно, из-за того, на что они способны.
- Generators — это выполнение функций, которые можно приостановить и возобновить позже.
- Generators полезны при реализации таких концепций, как «ленивое выполнение». По сути, это означает, что, приостанавливая и возобновляя выполнение по желанию, мы можем извлекать значения только тогда, когда нам это необходимо.
GeneratorУ нас есть два ключевых метода ниже.
- Метод доходности – Метод доходности вызывается в функции, чтобы остановить выполнение функции на конкретной строке, где вызывается метод доходности.
- Следующий метод – Этот метод вызывается из основного приложения для возобновления выполнения функции, имеющей метод доходности. Выполнение функции будет продолжаться до следующего метода доходности или до конца метода.
Давайте посмотрим на пример того, как можно использовать генераторы.
В нашем примере у нас будет простая функция Add, которая будет добавлять 2 числа, но мы будем продолжать останавливать выполнение метода в разных точках, чтобы продемонстрировать, как можно использовать генераторы.
function* Add(x) { yield x + 1; var y = yield(null); y = 6 return x + y; } var gen = Add(5); gen.next(); gen.next();
Код Пояснение
- Первым шагом является определение «функции» нашего генератора. Обратите внимание, что это делается путем добавления «*» к ключевому слову функции. Затем мы определяем функцию под названием Add, которая принимает параметр x.
- Ключевое слово доходности является специфичным для генераторов. Это делает его мощной конструкцией для приостановки функции в середине чего-либо. Итак, здесь выполнение функции будет остановлено до тех пор, пока мы не вызовем функцию next(), что будет выполнено на шаге 4. В этот момент значение x станет равным 6 и выполнение функции будет остановлено.
- Здесь мы сначала вызываем функцию генератора и отправляем значение 5 в нашу функцию Add. Это значение будет подставлено в параметр x нашей функции Add.
- Как только мы вызовем функцию next(), функция Add() возобновит выполнение. Когда будет выполнен следующий оператор var y= yield(null), функция Add() снова прекратит выполнение.
- Теперь после повторного вызова функции next() будут выполнены следующие операторы, а объединенное значение x=5 и y=6 будет добавлено и возвращено.
Обратные вызовы против генераторов
Generatorиспользуются для решения проблемы так называемого ада обратных вызовов. Иногда во время разработки приложения Node.js функции обратного вызова становятся настолько вложенными, что использовать функции обратного вызова становится слишком сложно.
Вот тут-то и пригодятся генераторы. Одним из наиболее распространенных примеров этого является создание функций таймера.
Давайте посмотрим на приведенный ниже пример того, как генераторы могут оказаться полезными для обратных вызовов.
В нашем примере будет создана простая функция задержки по времени. Затем мы хотели бы вызвать эту функцию с задержкой 1000, 2000 и 3000 мс.
Шаг 1) Определите нашу функцию обратного вызова с необходимым кодом задержки.
function Timedelay(ptime, callback) { setTimeout(function() { callback("Pausing for " + ptime); }, time); }
Код Пояснение
- Здесь мы создаем функцию Timedelay с параметром ptime. Это потребует необходимой задержки по времени, которую мы хотим ввести в нашем приложении.
- Следующим шагом будет создание сообщения, которое будет отображаться пользователю о том, что приложение будет приостановлено на указанное количество миллисекунд.
Шаг 2) Теперь давайте посмотрим на код, если бы мы включили обратные вызовы. Предположим, мы хотим включить обратные вызовы на основе значений 1000, 2000 и 3000 миллисекунд. Код ниже показывает, как нам нужно реализовать их с помощью обратных вызовов.
Timedelay(1000, function(message) { console.log(msg); Timedelay(2000, function(message) { console.log(msg); Timedelay(3000, function(message) { console.log(msg); }) }) })
Код Пояснение
- Мы вызываем Timedelay как обратный вызов со значением 1000.
- Далее мы хотим снова вызвать функцию Timedelay со значением 2000.
- Наконец, мы хотим снова вызвать функцию Timedelay со значением 3000.
Из приведенного выше кода вы можете видеть, что он становится более запутанным, поскольку мы хотим начать вызывать функцию несколько раз.
Шаг 3) Теперь посмотрим, как реализовать тот же код с помощью генераторов. Из приведенного ниже кода вы теперь можете увидеть, насколько просто стало реализовать функцию Timedelay с помощью генераторов.
function* Messages() { console,log(yield(Timedelay(1000, function(){}))); console,log(yield(Timedelay(2000, function(){}))); console,log(yield(Timedelay(3000, function(){}))); }
Код Пояснение
- Сначала мы определяем функцию-генератор, которая будет использоваться для вызова нашей функции Timedelay.
- Мы вызываем функцию Yield вместе с функцией Timedelay со значением параметра 1000.
- Затем мы вызываем функцию Yield вместе с функцией Timedelay со значением параметра 2000.
- Наконец, мы вызываем функцию Yield вместе с функцией Timedelay со значением параметра 3000.
Резюме
Generators также можно использовать для облегчения проблем с вложенными обратными вызовами и устранения так называемого ада обратных вызовов. Generators используются для остановки обработки функции. Это достигается за счет использования метода Yield в асинхронной функции.