V předchozích výukových programech byste viděli funkce zpětného volání, které se používají pro asynchronní události. Funkce zpětného volání se ale někdy mohou stát noční můrou, když se začnou vnořovat, a program začne být dlouhý a složitý.
V tomto výukovém programu se naučíte
- Co jsou sliby?
- Zpětná volání k slibům
- Jednání s vnořenými sliby
- Vytvoření vlastního slibu
Co jsou sliby?
Než začneme s přísliby, pojďme se nejprve znovu podívat, jaké jsou funkce „zpětného volání“ v Node.js. V předchozích kapitolách jsme tyto funkce zpětného volání viděli hodně, pojďme si tedy rychle projít jednu z nich.
Následující příklad ukazuje fragment kódu, který se používá k připojení k databázi MongoDB ak provedení operace aktualizace u jednoho ze záznamů v databázi.
-
Ve výše uvedeném kódu je část funkce (err, db) známá jako deklarace funkce anonymního nebo zpětného volání. Když MongoClient vytvoří připojení k databázi MongoDB, vrátí se po dokončení operace připojení k funkci zpětného volání. Takže v jistém smyslu se operace připojení dějí na pozadí, a když je hotovo, volá naši funkci zpětného volání. Nezapomeňte, že toto je jeden z klíčových bodů Node.js, který umožňuje souběžné provádění mnoha operací, a tedy neblokuje žádnému uživateli provedení operace.
-
Druhý blok kódu je proveden, když je funkce zpětného volání skutečně volána. Funkce zpětného volání pouze aktualizuje jeden záznam v naší databázi MongoDB.
Co je tedy slib? Slib je jen vylepšení funkcí zpětného volání v Node.js. Během životního cyklu vývoje může existovat instance, kde byste museli vnořovat více funkcí zpětného volání dohromady. To může být v určitém okamžiku trochu chaotické a obtížně udržovatelné. Stručně řečeno, slib je vylepšení zpětných volání, která směřuje ke zmírnění těchto problémů.
Základní syntaxe příslibu je uvedena níže;
var promise = doSomethingAync()promise.then(onFulfilled, onRejected)
- „doSomethingAync“ je jakékoli zpětné volání nebo asynchronní funkce, která provádí určitý druh zpracování.
- Tentokrát při definování zpětného volání existuje hodnota, která je vrácena a nazývá se „slib“.
- Když je slib vrácen, může mít 2 výstupy. To je definováno klauzulí „then“. Buď může být operace úspěšná, což je označeno parametrem 'onFulfilled'. Nebo to může mít chybu, která je označena parametrem 'onRejected'.
Poznámka: Klíčovým aspektem slibu je tedy návratová hodnota. Při práci s normálními zpětnými voláními v Node.js. neexistuje žádný koncept návratové hodnoty. Z důvodu návratové hodnoty máme větší kontrolu nad tím, jak lze definovat funkci zpětného volání.
V dalším tématu uvidíme příklad slibů a jejich přínosu ze zpětných volání.
Zpětná volání k slibům
Nyní se podívejme na příklad toho, jak můžeme použít „sliby“ v rámci aplikace Node.js. Aby bylo možné použít sliby v aplikaci Node.js, je třeba nejprve stáhnout a nainstalovat modul „slib“.
Poté upravíme náš kód, jak je znázorněno níže, který pomocí slibů aktualizuje jméno zaměstnance ve sbírce „Zaměstnanec“.
Krok 1) Instalace modulů NPM
Chcete-li používat sliby z aplikace Node JS, je vyžadován modul slibu. Chcete-li nainstalovat modul slibů, spusťte následující příkaz
slib instalace NPM
Krok 2) Upravte kód tak, aby obsahoval sliby
var Promise = require('promise');var MongoClient = require('mongodb').MongoClient;var url = 'mongodb://localhost/EmployeeDB';MongoClient.connect(url).then(function(err, db) {db.collection('Employee').updateOne({"EmployeeName": "Martin"}, {$set: {"EmployeeName": "Mohan"}});});
Vysvětlení kódu: -
- První částí je zahrnout modul „slib“, který nám umožní používat funkci slibu v našem kódu.
- Nyní můžeme k naší funkci MongoClient.connect připojit funkci „then“. To, co to dělá, je, že když je navázáno připojení k databázi, musíme provést fragment kódu, který je definován poté.
- Nakonec definujeme náš fragment kódu, který provádí aktualizaci jména zaměstnance zaměstnance se jménem „Martin“ na „Mohan“.
Poznámka:-
Pokud nyní zkontrolujete obsah své databáze MongoDB, zjistíte, že pokud existuje záznam s názvem EmployeeName „Martina“, bude aktualizován na „Mohan“.
Chcete-li zkontrolovat, zda byla data správně vložena do databáze, musíte v MongoDB provést následující příkazy
- Použijte EmployeeDB
- db.Employee.find ({EmployeeName: Mohan})
První příkaz zajišťuje, že jste připojeni k databázi EmployeeDb. Druhý příkaz hledá záznam, který má jméno zaměstnance „Mohan“.
Jednání s vnořenými sliby
Při definování slibů je třeba poznamenat, že samotná metoda „then“ vrací slib. V jistém smyslu tedy mohou být sliby navzájem vnořené nebo zřetězené.
V níže uvedeném příkladu používáme zřetězení k definování 2 funkcí zpětného volání, které obě vkládají záznam do databáze MongoDB.
( Poznámka : Chaining je koncept používaný k propojení provádění metod mezi sebou. Předpokládejme, že pokud vaše aplikace měla 2 metody zvané „methodA“ a „methodB.“ A logika byla taková, že „methodB“ by mělo být voláno po „methodA,“ pak byste provedli řetězení provádění takovým způsobem, že se 'methodB' zavolá přímo po 'methodA.')
Klíčovou věcí, kterou je třeba si v tomto příkladu všimnout, je, že se kód stává čistším, čitelným a udržovatelným pomocí vnořených slibů.
var Promise = require('promise');var MongoClient = require('mongodb').MongoClient;var url = 'mongodb://localhost/EmployeeDB';MongoClient.connect(url).then(function(db) {db.collection('Employee').insertOne({Employeeid: 4,EmployeeName: "NewEmployee"}).then(function(db1) {db1.collection('Employee').insertOne({Employeeid: 5,EmployeeName: "NewEmployee1"})})});
Vysvětlení kódu: -
- Nyní definujeme 2 klauzule „then“, které se provádějí jedna po druhé. V první klauzuli then předáváme parametr 'db', který obsahuje naše připojení k databázi. Potom používáme vlastnost kolekce připojení 'db' k vložení záznamů do kolekce 'Zaměstnanec'. Metoda 'insertOne' se používá k vložení skutečného dokumentu do kolekce Zaměstnanec.
- Poté použijeme klauzuli 2. pak také k vložení dalšího záznamu do databáze.
Pokud nyní zkontrolujete obsah své databáze MongoDB, najdete 2 záznamy vložené do databáze MongoDB.
Vytvoření vlastního slibu
Vlastní slib lze vytvořit pomocí uzlového modulu s názvem „q“. Knihovnu 'q' je třeba stáhnout a nainstalovat pomocí správce balíčků uzlů. Po použití knihovny „q“ lze volat metodu „denodeify“, která způsobí, že se z jakékoli funkce stane funkce, která vrací slib.
V níže uvedeném příkladu vytvoříme jednoduchou funkci nazvanou „Přidat“, která přidá 2 čísla. Tuto funkci převedeme na funkci, abychom vrátili slib.
Jakmile to uděláme, použijeme slib vrácený funkcí Přidat k zobrazení zprávy v console.log.
Postupujeme podle níže uvedených kroků k vytvoření naší vlastní funkce, abychom vrátili slib.
Krok 1) Instalace modulů NPM
Chcete-li použít „q“ v rámci aplikace Node JS, je vyžadován modul „q“. Chcete-li nainstalovat modul 'q', spusťte následující příkaz
npm install q
Krok 2) Definujte následující kód, který bude použit k vytvoření vlastního slibu.
Vysvětlení kódu: -
- Prvním bitem je zahrnutí knihovny 'q' pomocí klíčového slova require. Pomocí této knihovny budeme moci definovat jakoukoli funkci pro vrácení zpětného volání.
- Vytváříme funkci nazvanou Přidat, která přidá 2 čísla definovaná v proměnných a a b. Součet těchto hodnot bude uložen v proměnné c.
- Poté používáme knihovnu q k denodeifikaci (metoda použitá k převodu libovolné funkce na funkci, která by vrátila slib) naši funkci Add nebo v jiném převodu naší funkce Add na funkci, která vrací slib.
- Nyní voláme naši funkci „Přidat“ a jsme schopni získat návratovou slibnou hodnotu kvůli předchozímu kroku, který jsme provedli denodeify funkce Přidat.
- Klíčové slovo „then“ se používá k určení, že pokud je funkce úspěšně spuštěna, zobrazí v konzole.log řetězec „Funkce přidání byla dokončena“.
Když je spuštěn výše uvedený kód, výstup "Funkce přidání je dokončen" se zobrazí v console.log, jak je znázorněno níže.
souhrn
- Použití funkcí zpětného volání v Node.js má své nevýhody. Někdy během procesu vývoje může vnořené použití funkcí zpětného volání způsobit, že kód bude messier a bude obtížné jej udržovat.
- Většinu problémů s vnořenými funkcemi zpětného volání lze zmírnit pomocí slibů a generátorů v node.js
- Promise je hodnota vrácená asynchronní funkcí, která označuje dokončení zpracování prováděného asynchronní funkcí.
- Promises can be nested within each other to make code look better and easier to maintain when an asynchronous function need to be called after another asynchronous function