Implementace Async a čekat s generátory

Foto Blake Connally na Unsplash

Dnes můžeme díky asynchronním a očekávaným klíčovým slovům psát náš asynchronní kód synchronním způsobem. To usnadňuje čtení a porozumění. Nedávno jsem však přemýšlel, jak by bylo možné dosáhnout stejného efektu bez použití těchto klíčových slov.

Ukázalo se, že je to celkem jednoduché, protože chování asynchronního a očekávaného lze snadno generovat pomocí generátorů. Pojďme se podívat!

Pokračujte, klonujte úložiště a začněme.

Generátory

Budu předpokládat, že s generátory nemáte žádné zkušenosti, protože popravdě, většinou nejsou zvláště užitečné a bez nich se snadno zvládnete. Nebojte se - začneme rychlým připomenutím.

Generátory jsou objekty vytvořené funkcemi generátoru - funkce s * (hvězdičkou) vedle jejich názvu.

Tyto generátory mají úžasnou schopnost, která nám umožňuje zastavit provádění kódu - kdykoli chceme - pomocí výtěžku klíčového slova.

Zvažte tento příklad:

const generator = (function * () {
  // čeká na .next ()
  const a = výtěžek 5;
  // čeká na .next ()
  console.log (a); // => 15
}) ();

console.log (generator.next ()); // => {done: false, value: 5}
console.log (generator.next (15)); // => {done: true, value: undefined}

Vzhledem k tomu, že se jedná o absolutní základy, doporučuji vám, abyste si před dalším procházením přečetli tento článek, abyste získali přehled o tom, co se zde skutečně děje.

Pokud máte pocit, že máte silné pochopení základních myšlenek, můžeme jít dál.

Počkejte, počkejte minutu

Nepřemýšleli jste někdy, jak to opravdu funguje?

Nějak to jen čeká, až náš slib vrátí hodnotu a pokračuje v provádění. Pro mě se to zdá jako něco, co by generátor mohl udělat po malém vyladění.

Můžeme udělat jen to, že vezmeme každou vynesenou hodnotu, vložíme ji do slibu a potom počkáme, až bude slib vyřešen. Poté ji prostě vrátíme do generátoru voláním generator.next (resolvedValue).

To zní jako plán. Nejprve si ale napíšeme několik testů, abychom se ujistili, že všechno funguje podle očekávání.

Co by naše funkce asynq měla dělat:

  • Před pokračováním ve zpracování vyčkejte na asynchronní kód
  • vrátí příslib s vrácenou hodnotou z funkce
  • provést pokus / chytit práci na asynchronním kódu

Poznámka: Protože používáme generátory, naše očekávání se stane výnosem.

Dobře, skvělé! Nyní můžeme mluvit o implementaci.

Naše funkce asynq bere jako parametr generátor funkce - voláním vytváříme generátor.

Pro jistotu voláme isGeneratorLike, který zkontroluje, zda přijatá hodnota je objekt a má další metody a vyvolá.

Potom rekurzivně spotřebováváme každé klíčové slovo výnosu voláním generátoru.next (zajištěná hodnota). Čekáme, až bude vrácený slib vyřízen, a pak jeho výsledek vrátíme zpět generátoru opakováním celého procesu.

Musíme také připojit manipulátor úlovků, takže pokud funkce vyvolá výjimku, můžeme ji zachytit a vrátit výjimku uvnitř funkce voláním generátoru.throw (chyba).

Nyní budou případné chyby řešeny pomocí úlovků. Pokud by neexistoval blok try / catch, chyba jednoduše zastaví provádění - stejně jako jakákoli neošetřená výjimka - a naše funkce vrátí odmítnutý slib.

Když je generátor hotový, vracíme jeho návratovou hodnotu ve slibu.

Nyní, po spuštění našich testů, můžeme vidět, že všechno funguje podle očekávání.

Zabalení

I když tato implementace pravděpodobně není implementace používaná uvnitř motorů JavaScriptu, určitě se cítí dobře, abychom mohli něco takového dělat sami.

Nebojte se znovu projít kód. Čím lépe chápete základní myšlenky, tím více budete moci ocenit brilanci tvůrců asynchronních a čekajících klíčových slov.

Děkujeme za přečtení! Doufám, že jste tento článek shledali informativní. Doufám také, že vám to pomohlo vidět, že v asynchronních a čekajících klíčových slovech není zahrnuta žádná magie a že je lze snadno nahradit generátory.

Máte-li jakékoli dotazy nebo připomínky, neváhejte je vložit do níže uvedené poznámky nebo nám pošlete zprávu.

Podívejte se na moje sociální média!

Připojte se k mému zpravodaji!

Původně zveřejněno na www.mcieslar.com 6. srpna 2018.