В этом уроке мы узнаем о генераторах и их различиях с обратными вызовами
Какие генераторы?
Генераторы в Node.js стали довольно популярными в последнее время, и это, вероятно, из-за того, что они способны делать.
- Генераторы — это выполнение функций, которые могут быть приостановлены и возобновлены на более позднем этапе.
- Генераторы полезны при выполнении таких понятий, как «ленивое выполнение». В основном это означает, что, приостановив выполнение и возобновив по своему усмотрению, мы можем получить значения только тогда, когда нам это нужно.
Генераторы имеют следующие 2 ключевых метода
- Метод доходности — метод доходности вызывается в функции, чтобы остановить выполнение функции в конкретной строке, где вызывается метод доходности.
- Следующий метод — этот метод вызывается из основного приложения, чтобы возобновить выполнение функции, имеющей метод yield. Выполнение функции будет продолжаться до следующего метода yield или до конца метода.
Давайте рассмотрим пример использования генераторов.
В нашем примере у нас будет простая функция 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.
- Ключевое слово yield является специфическим для генераторов. Это делает его мощной конструкцией для приостановки функции в середине всего. Поэтому здесь выполнение функции будет остановлено до тех пор, пока мы не вызовем функцию next (), что будет сделано в шаге 4. В этот момент значение x станет 6, и выполнение функции будет остановлено.
- Здесь мы сначала вызываем функцию генератора и отправляем значение 5 в нашу функцию Add. Это значение будет подставлено в параметр x нашей функции Add.
- Как только мы вызовем функцию next (), функция Add () возобновит выполнение. Когда будет выполнен следующий оператор var y = yield (null), функция Add () снова прекратит выполнение.
- Теперь после повторного вызова функции next () будут выполняться следующие операторы, и объединенное значение x = 5 и y = 6 будет добавлено и возвращено.
Обратные вызовы против генераторов
Генераторы используются для решения проблемы так называемого ада обратного вызова. Иногда функции обратного вызова становятся настолько вложенными во время разработки приложения 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 в качестве значения параметра.
Резюме
Генераторы также могут использоваться для устранения проблем с вложенными обратными вызовами и помощи в удалении того, что известно как ад обратного вызова. Генераторы используются для остановки обработки функции. Это достигается путем использования метода yield в асинхронной функции.