Node.js Promise Tutorial
V předchozích kurzech jste viděli funkce zpětného volání, které se používají pro asynchronní události. Někdy se však funkce zpětného volání mohou stát noční můrou, když se začnou vnořovat a program začne být dlouhý a složitý.
Co jsou sliby?
Než začneme se sliby, podívejme se nejprve, co jsou funkce „zpětného volání“ v Node.js. Tyto funkce zpětného volání jsme již mnohokrát viděli v předchozích kapitolách, pojďme si tedy rychle projít jednu z nich.
Níže uvedený příklad ukazuje fragment kódu, který se používá k připojení k a MongoDB databázi a proveďte operaci aktualizace jednoho ze záznamů v databázi.
- Ve výše uvedeném kódu je část funkce (err,db) známá jako deklarace anonymní nebo zpětné funkce. Když MongoClient vytvoří připojení k MongoDB databáze se po dokončení operace připojení vrátí k funkci zpětného volání. Takže v jistém smyslu operace připojení probíhají na pozadí, a když jsou hotové, zavolá naši funkci zpětného volání. Pamatujte, že toto je jeden z klíčových bodů Node.js, který umožňuje souběžné provádění mnoha operací a neblokuje tak žádného uživatele v provedení operace.
- Druhý blok kódu je to, co se provede při skutečném volání funkce zpětného volání. Funkce zpětného volání pouze aktualizuje jeden záznam v našem MongoDB databáze.
Co je tedy slib? No, slib je jen vylepšení funkcí zpětného volání v Node.js. Během životního cyklu vývoje může nastat případ, kdy budete muset vnořit více funkcí zpětného volání dohromady. To může být v určitém okamžiku poněkud chaotické a obtížné udržovat. Stručně řečeno, příslib je vylepšením zpětných volání, které se zaměřuje na zmírnění těchto problémů.
Základní syntaxe 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í nějaký druh zpracování.
- Tentokrát je při definování zpětného volání vrácena hodnota, která se nazývá „slib“.
- Když je příslib vrácen, může mít 2 výstupy. To je definováno klauzulí „pak“. Operace může být úspěšná, což je označeno parametrem 'onFulfilled'. Nebo může mít chybu, která je označena parametrem 'onRejected'.
Poznámka: Klíčovým aspektem příslibu je tedy návratnost. Při práci s normálními zpětnými voláními v Node.js neexistuje žádná koncepce návratové hodnoty. Díky návratové hodnotě 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 užitek ze zpětných volání.
Zpětná volání ke slibům
Nyní se podívejme na příklad toho, jak můžeme použít „sliby“ z aplikace Node.js. Aby bylo možné používat sliby v aplikaci Node.js, je třeba nejprve stáhnout a nainstalovat modul „promise“.
Poté upravíme náš kód, jak je uvedeno níže, který aktualizuje jméno zaměstnance v kolekci „Zaměstnanec“ pomocí slibů.
Krok 1) Instalace modulů NPM
Chcete-li používat Promises z aplikace Node JS, je vyžadován modul slibu. Chcete-li nainstalovat modul slib, spusťte níže uvedený příkaz
slib instalace npm
Krok 2) Upravte kód tak, aby zahrnoval 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 zahrnutí modulu 'promise', 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 'pak'. Takže když je navázáno spojení s databází, musíme provést fragment kódu definovaný poté.
- Nakonec definujeme náš úryvek kódu, který aktualizuje jméno zaměstnance zaměstnance se jménem „Martin“ na „Mohan“.
Poznámka: -
Pokud nyní zkontrolujete obsah svého MongoDB databáze, zjistíte, že pokud existuje záznam se jménem zaměstnance „Martin“, bude aktualizován na „Mohan“.
Chcete-li zkontrolovat, zda byla data správně vložena do databáze, musíte provést následující příkazy MongoDB
- 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“.
Vypořádání se s vnořenými sliby
Při definování slibů je třeba poznamenat, že samotná metoda „pak“ vrací slib. Takže v jistém smyslu mohou být sliby vnořené nebo řetězené k sobě navzájem.
V níže uvedeném příkladu používáme řetězení k definování 2 funkcí zpětného volání, z nichž obě vkládají záznam do MongoDB databáze.
(Hodnocení: Řetězení je koncept používaný ke vzájemnému propojení provádění metod. Předpokládejme, že vaše aplikace měla 2 metody nazvané „methodA“ a „methodB“. A logika byla taková, že 'methodB' by měla být volána po 'methodA', pak byste zřetězovali provádění takovým způsobem, že 'methodB' se volá přímo za 'methodA').
Klíčová věc, kterou je třeba v tomto příkladu poznamenat, je, že kód se stává čistším, čitelným a udržovatelným pomocí vnořených pří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 „pak“, které se provádějí jedna po druhé. V první klauzuli potom 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 vkládání záznamů do kolekce 'Zaměstnanec'. Metoda 'insertOne' se používá k vložení skutečného dokumentu do kolekce Employee.
- Pak používáme 2nd pak klauzule také pro vložení dalšího záznamu do databáze.
Pokud nyní zkontrolujete obsah svého MongoDB databáze, najdete 2 záznamy vložené do MongoDB databáze.
Vytvoření vlastního příslibu
Vlastní příslib lze vytvořit pomocí modulu uzlu 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 zavolat 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 s názvem „Přidat“, která sečte 2 čísla. Tuto funkci převedeme na funkci, která vrátí slib.
Jakmile to uděláme, použijeme příslib vrácený funkcí Přidat k zobrazení zprávy v console.log.
Pojďme se řídit níže uvedenými kroky k vytvoření naší vlastní funkce pro vrácení slibu.
Krok 1) Instalace modulů NPM
Chcete-li použít 'q' z aplikace Node JS, je vyžadován modul 'q'. Chcete-li nainstalovat modul 'q', spusťte níže uvedený příkaz
instalace npm q
Krok 2) Definujte následující kód, který bude použit k vytvoření vlastního příslibu.
Vysvětlení kódu:-
- První bit je zahrnout knihovnu 'q' pomocí klíčového slova require. Pomocí této knihovny budeme schopni definovat libovolnou funkci pro vrácení zpětného volání.
- Vytváříme funkci s názvem Add, která sečte 2 čísla definovaná v proměnných a a b. Součet těchto hodnot bude uložen v proměnné c.
- Potom používáme knihovnu q k denodeifikaci (metoda používaná k převodu jakékoli funkce na funkci, která by vrátila slib) naší funkce Add nebo k jinému převodu naší funkce Add na funkci, která vrací slib.
- Nyní voláme naši funkci „Přidat“ a jsme schopni získat hodnotu návratového příslibu díky předchozímu kroku, který jsme provedli při denodeifikaci funkce Přidat.
- Používá se klíčové slovo 'then', které určuje, že pokud je funkce úspěšně provedena, zobrazí se v konzole.log řetězec „Funkce přidání dokončena“.
Po spuštění výše uvedeného kódu se v konzole.log zobrazí výstup „Funkce přidání dokončena“, jak je uvedeno níže.
Shrnutí
- Používání 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 složitější a obtížně se udržuje.
- Většinu problémů s vnořenými funkcemi zpětného volání lze zmírnit použitím 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í.
- Sliby mohou být vnořeny do sebe, aby kód vypadal lépe a snáze se udržoval, když je třeba volat asynchronní funkci po jiné asynchronní funkci