Node.js Generators & Сравнете с обратни повиквания
В този урок ще научим за Generators и техните разлики с обратните извиквания
Какво представляват генераторите?
Generatorса станали доста известни в Node.js в последно време и това вероятно се дължи на това, което са способни да направят.
- Generators са изпълнения на функции, които могат да бъдат спрени и възобновени на по-късен етап.
- Generatorса полезни при изпълнение на концепции като „мързеливо изпълнение“. Това основно означава, че чрез спиране на изпълнението и възобновяване по желание, ние сме в състояние да изтегляме стойности само когато имаме нужда.
Generatorимат следните 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 ще бъде добавена и върната.
Обратни извиквания срещу генератори
Generators се използват за решаване на проблема с това, което е известно като ад за обратно извикване. Понякога функциите за обратно извикване стават толкова вложени по време на разработката на Node.js приложение, че просто става твърде сложно да се използват функции за обратно извикване.
Тук са полезни генераторите. Един от най-често срещаните примери за това е създаването на таймерни функции.
Нека видим примера по-долу за това как генераторите могат да се окажат полезни при обратни извиквания.
Нашият пример просто ще създаде проста функция за забавяне на времето. След това бихме искали да извикаме тази функция, включваща забавяне от 1000, 2000 и 3000 ms.
Стъпка 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(){}))); }
Обяснение на кода
- Първо дефинираме генераторна функция, която ще се използва за извикване на нашата функция за забавяне на времето.
- Извикваме функцията Yield заедно с функцията Timedelay с 1000 като стойност на параметъра.
- След това извикваме функцията Yield заедно с функцията Timedelay с 2000 като стойност на параметъра.
- И накрая, извикваме функцията Yield заедно с функцията Timedelay с 3000 като стойност на параметъра.
Oбобщение
Generators може също да се използва за облекчаване на проблемите с вложени обратни извиквания и подпомагане при премахването на това, което е известно като ада на обратното извикване. Generators се използват за спиране на обработката на функция. Това се постига чрез използване на метода 'yield' в асинхронната функция.