Přísliby mě nadchly už před rokem, kdy byly představeny. Ačkoli se objevuje spousta příspěvků a názorů, sliby neudělají váš kód výkonnějším… udělají ho jednodušším na čtení a pochopení (což se u mě často počítá mnohem víc!)
V první části tohoto příspěvku vysvětlím základní strukturu slibů. Pokud jste to zvládli, klidně přejděte na druhou polovinu příspěvku.
Přísliby vysvětlené srozumitelně
Tady je základní struktura slibu v Javascriptu:
Tady je docela typický (a neuchopitelný) kousek kódu. Pokusím se rozebrat, o co jde.
Pro začátek se zaměřte pouze na řádky 1-15:
- Tady je instanciace. Tento řádek v podstatě vytváří slib. Příslib v JS potřebuje něco udělat, nějaký úkol. Takže funkce, kterou zde vidíte předávat – function (resolve,reject) {…} je onou úlohou
- Dále vidíte tělo úlohy. Zde můžete dělat různé věci. Někde v tomto bloku kódu musíte rozhodnout, zda věci proběhly dobře, nebo ne. Například pokud jste toto místo používali k načtení obrázku, buď jste ho obdrželi (proběhlo dobře)… nebo ne (ne tak dobře).
- Pokud věci proběhly dobře, zavoláte nějakou funkci, která tento slib označí jako „vyřešený“. Pokud věci neproběhly podle plánu, tento slib „odmítnete“. (podrobněji si o tom povíme za chvíli)
Nyní se zaměříme na zbývající část úryvku kódu, řádky 17-27:
- Na řádcích 1-15 jste zatím pouze definovali svůj objekt Promise
- Na řádcích 17 & 22 k němu v podstatě připojíte obsluhu
- promise.XXXX (kde XXX může být „.then“ nebo „.catch“ atd.) v podstatě spustíte funkci definovanou v slibu (řádky 1-15). Podle toho, jak věci dopadly (vyřešeny nebo zamítnuty), zavolají funkce v „.then“, respektive „.catch“. Takže pokud byl váš slib vyřešen (…věci dopadly dobře), provede se funkce uvnitř .then(…), jinak se provede funkce v .catch(…).
NOTE:
- „.then(function)“ vrací slib. Také můžete volat „.then(…)“ nebo „.catch(…)“ pouze na objektech Promise.
Teď, když jsme probrali základy, se podíváme na zajímavější příklad toho, co můžeme s Promise dělat.
Řetězení Promise pro provedení více požadavků
Problém: Nedávno jsem narazil na situaci, kdy jsem potřeboval postupně načíst několik adres URL. Odpověď pro každou adresu URL však musela být zpracována jinak v závislosti na adrese URL.
Pro účely tohoto příspěvku předpokládejme, že načítané adresy URL jsou:
- google.com
- apple.com
- amazon.com
Tady je zjednodušená verze skriptu, který jsem použil k vyřízení této úlohy:
Rozložíme si to:
- Řádky 1-11: Vytvoříme jednoduchý wrapper kolem metody AJAX Get, kterou poskytuje jQuery. Ten jednoduše předá odpověď zadanému zpětnému volání.
- Řádky 18-51: Poté vytvořím tři funkce (ano! Funkce!), které vrátí JS Promise
- Každý promise interně udělá toto – použije Ajax wrapper k načtení své url, a jakmile obdrží data/odpověď, něco s daty provede a nakonec zavolá „resolve()“
- V řádku 54: Tyto sliby řetězuji jeden za druhým. Všimněte si, že každá z těchto funkcí vrací slib (a sama o sobě není slibem). Proto používám „first()“.then(…) na rozdíl od „first.then(…)“
Pro další objasnění uvádím způsob, jak se na řetězení slibů dívat.
Takto můžete postupně získat každou adresu URL, zpracovat ji podle potřeby a spustit funkci „resolved()“, která spustí další slib v řetězci 🙂
Poznámka: pokud se pokusíte výše uvedený úryvek kódu spustit v prohlížeči, budete muset povolit CORS. Zde je rozšíření pro Chrome, které vám s tím pomůže jednoduchým kliknutím.
Doufám, že se vám tento příspěvek líbil.