Programovanie

Asynchrónny JavaScript: Spätné väzby a sľuby vysvetlené

Zaobchádzanie s asynchrónnym kódom, čo znamená, že sa nespustí okamžite, ako sú webové požiadavky alebo časovače, môže byť zložité. JavaScript nám ponúka dva spôsoby, ako zvládnuť asynchrónne správanie: spätné volania a sľuby.

Spätné volania boli jediným natívne podporovaným spôsobom riešenia asynchronného kódu do roku 2016, kedy Sľub objekt bol zavedený do jazyka. Vývojári JavaScriptu však podobné funkcie implementovali už roky predtým, ako sa na scénu dostali sľuby. Pozrime sa na niektoré rozdiely medzi spätnými volaniami a prísľubmi a pozrime sa, ako sa vyrovnáme s koordináciou viacerých sľubov.

Asynchrónne funkcie, ktoré používajú spätné volania, berú funkciu ako parameter, ktorý sa zavolá po dokončení práce. Ak ste niečo také použili setTimeout v prehliadači ste použili spätné volania.

// Svoje spätné volanie môžete definovať osobitne ...

nechajte myCallback = () => {

console.log ('Volal!');

};

setTimeout (myCallback, 3000);

// ... ale je tiež bežné vidieť spätné volania definované v riadku

setTimeout (() => {

console.log ('Volal!');

}, 3000);

Funkcia, ktorá berie spätné volanie, ho zvyčajne berie ako svoj posledný argument. Toto nie je prípad vyššie, takže sa tvárme, že sa volá nová funkcia počkaj to je ako setTimeout ale berie prvé dva argumenty v opačnom poradí:

// Použili by sme našu novú funkciu takto:

waitCallback (3000, () => {

console.log ('Volal!');

});

Vnorené spätné volania a pyramída skazy

Spätné volania fungujú dobre pri spracovaní asynchrónneho kódu, sú však zložité, keď začnete koordinovať viac asynchrónnych funkcií. Napríklad, ak sme chceli počkať dve sekundy a niečo prihlásiť, potom počkať tri sekundy a prihlásiť niečo iné, potom počkať štyri sekundy a prihlásiť niečo iné, naša syntax sa stane hlboko vnorenou.

// Použili by sme našu novú funkciu takto:

waitCallback (2000, () => {

console.log ('Prvé spätné volanie!');

waitCallback (3000, () => {

console.log ('Druhé spätné volanie!');

waitCallback (4000, () => {

console.log ('Tretie spätné volanie!');

    });

  });

});

Môže sa to javiť ako triviálny príklad (a je to tak), ale nie je nezvyčajné zadávať niekoľko webových požiadaviek za sebou na základe výsledkov návratnosti predchádzajúcej žiadosti. Ak vaša knižnica AJAX používa spätné volania, uvidíte vyššie uvedenú štruktúru. V príkladoch, ktoré sú hlbšie vnorené, uvidíte to, čo sa označuje ako pyramída skazy, ktorá dostala svoj názov podľa tvaru pyramídy vytvorenej v odsadenom medzere na začiatku riadkov.

Ako vidíte, náš kód je štrukturálne rozbitý a ťažšie čitateľný pri práci s asynchrónnymi funkciami, ktoré sa musia vykonávať postupne. Ale bude to ešte zložitejšie. Predstavte si, že by sme chceli iniciovať tri alebo štyri webové požiadavky a vykonať určitú úlohu až potom, čo sa všetky vrátia. Odporúčam vám, aby ste sa o to pokúsili, ak ste sa s touto výzvou predtým nestretli.

Ľahšia asynchronizácia so sľubmi

Sľuby poskytujú flexibilnejšie rozhranie API na prácu s asynchrónnymi úlohami. Vyžaduje, aby bola funkcia napísaná tak, aby vracala a Sľub objekt, ktorý má niektoré štandardné funkcie na zvládnutie následného správania a koordináciu viacerých sľubov. Ak náš waitCallback funkcia bola Sľub-na základe by to trvalo iba jeden argument, čo je milisekunda čakania. Akákoľvek následná funkčnosť by bola pripútaný mimo sľub. Náš prvý príklad by vyzeral takto:

nechajte myHandler = () => {

console.log („Volané!“);

};

waitPromise (3000). potom (myHandler);

Vo vyššie uvedenom príklade waitPromise (3000) vracia a Sľub objekt, ktorý má niektoré metódy, ktoré môžeme použiť, ako napr potom. Keby sme chceli vykonávať niekoľko asynchrónnych funkcií jednu za druhou, mohli by sme sa pyramíde skazy vyhnúť pomocou sľubov. Tento kód prepísaný tak, aby podporoval náš nový prísľub, by vyzeral takto:

// Bez ohľadu na to, koľko máme sekvenčných asynchrónnych úloh, pyramídu nikdy neurobíme.

waitPromise (2000)

. potom (() => {

console.log ('Prvé spätné volanie!');

návrat waitPromise (3000);

  })

. potom (() => {

console.log ('Druhé spätné volanie!');

návrat waitPromise (4000);

  })

. potom (() => {

console.log ('Druhé spätné volanie!');

návrat waitPromise (4000);

  });

Ešte lepšie je, že ak potrebujeme koordinovať asynchrónne úlohy, ktoré podporujú prísľuby, môžeme ich použiť všetko, čo je statická metóda na Sľub objekt, ktorý prijíma niekoľko sľubov a spája ich do jedného. Vyzeralo by to takto:

Promise.all ([

waitPromise (2000),

waitPromise (3000),

waitPromise (4000)

]). potom (() => console.log ('Všetko sa stalo!'));

Budúci týždeň sa budeme ďalej zaoberať tým, ako sľuby fungujú a ako ich idiomaticky využiť. Ak sa práve učíte JavaScript alebo chcete vyskúšať svoje vedomosti, skúste to waitCallback alebo sa pokúste dosiahnuť ekvivalent Promise.all so spätnými volaniami.

Ako vždy, kontaktujte ma na Twitteri s akýmikoľvek komentármi alebo otázkami.

$config[zx-auto] not found$config[zx-overlay] not found