Programavimas

Asinchroninis „JavaScript“: paaiškinti atgaliniai skambučiai ir pažadai

Asinchroninio kodo, ty kodo, kuris nevykdomas iš karto, pvz., Žiniatinklio užklausos ar laikmačiai, sprendimas gali būti keblus. „JavaScript“ suteikia mums du būdus, kaip ištaisyti asinchroninį elgesį: skambučius ir pažadus.

Atšaukimas buvo vienintelis natūraliai palaikomas būdas kovoti su asinchroniniu kodu iki 2016 m., Kai Pažadas objektas buvo supažindintas su kalba. Tačiau „JavaScript“ kūrėjai panašų funkcionalumą įgyvendino savo metus prieš pasirodant pažadams. Pažvelkime į kai kuriuos skambučių ir pažadų skirtumus ir pažiūrėkime, kaip elgiamės derindami kelis pažadus.

Asinchroninės funkcijos, naudojančios atgalinius skambučius, parametrą laiko funkcija, kuri bus iškviesta, kai darbas bus baigtas. Jei naudojate kažką panašaus setTimeout naršyklėje naudojote atgalinius skambučius.

// Galite nustatyti savo atgalinį skambutį atskirai ...

tegul myCallback = () => {

console.log ('Skambinta!');

};

„setTimeout“ („myCallback“, 3000);

// ... bet taip pat dažnai matyti skambučius, apibrėžtus įterptai

setTimeout (() => {

console.log ('Skambinta!');

}, 3000);

Paprastai funkcija, kuri priima atgalinį skambutį, ją laiko paskutiniu argumentu. Aukščiau to nėra, todėl apsimeskime, kad yra nauja vadinama funkcija laukti kad yra kaip setTimeout bet pirmuosius du argumentus pateikia priešinga tvarka:

// Naudotume savo naują funkciją taip:

waitCallback (3000, () => {

console.log ('Skambinta!');

});

Lizdiniai skambučiai ir pražūties piramidė

Skambučiai puikiai tinka tvarkant asinchroninį kodą, tačiau jie tampa sudėtingi, kai pradedate koordinuoti kelias asinchronines funkcijas. Pavyzdžiui, jei norėjome palaukti dvi sekundes ir ką nors užregistruoti, tada palaukti tris sekundes ir užregistruoti ką nors kita, tada palaukti keturias sekundes ir užregistruoti ką nors kita, mūsų sintaksė tampa giliai įdėta.

// Mes naudotume savo naują funkciją taip:

waitCallback (2000, () => {

console.log ('Pirmasis skambutis!');

waitCallback (3000, () => {

console.log ('Antrasis skambinimas!');

waitCallback (4000, () => {

console.log ('Trečiasis atgalinis skambutis!');

    });

  });

});

Tai gali atrodyti nereikšmingas pavyzdys (ir yra), tačiau neretai pateikiamos kelios žiniatinklio užklausos iš eilės, remiantis ankstesnės užklausos grąžinimo rezultatais. Jei jūsų AJAX bibliotekoje naudojami atgaliniai skambučiai, pamatysite aukščiau pateiktą struktūrą. Giliau įterptuose pavyzdžiuose pamatysite tai, kas vadinama pasmerkimo piramide, kuri savo vardą gauna iš piramidės formos, padarytos eilučių pradžioje įspaustoje erdvėje.

Kaip matote, mūsų kodas yra struktūriškai supainiotas ir sunkiau įskaitomas, kai sprendžiamos asinchroninės funkcijos, kurios turi vykti nuosekliai. Bet tai darosi dar kebliau. Įsivaizduokite, jei norėtume inicijuoti tris ar keturias žiniatinklio užklausas ir atlikti tam tikrą užduotį tik jiems visiems grįžus. Raginu jus pabandyti tai padaryti, jei dar nesate susidūrę su iššūkiu.

Lengviau asinchronizuoti su pažadais

Pažadai suteikia lankstesnę API, skirtą asinchroninėms užduotims spręsti. Tam reikia, kad funkcija būtų parašyta taip, kad ji grąžintų a Pažadas objektas, kuris turi keletą standartinių savybių, kaip tvarkyti tolesnį elgesį ir derinti kelis pažadus. Jei mūsų palaukPaskambinimas funkcija buvo Pažadaspagrindu, tereikės tik vieno argumento, tai yra milisekundžių laukimo. Bet koks vėlesnis funkcionalumas būtų grandinėmis nevykęs pažadas. Pirmasis mūsų pavyzdys atrodytų taip:

tegul myHandler = () => {

console.log (‘Paskambinta!’);

};

palaukti Pažadas (3000). tada („myHandler“);

Aukščiau pateiktame pavyzdyje palaukti Pažadas (3000) grąžina a Pažadas objektas, kuriame yra keletas metodų, kuriuos galime naudoti, pvz tada. Jei norėtume vienas po kito vykdyti kelias asinchronines funkcijas, naudodamiesi pažadais galėtume išvengti pražūties piramidės. Šis kodas, perrašytas palaikyti mūsų naująjį pažadą, atrodys taip:

// Nesvarbu, kiek turime nuoseklių asinchroninių užduočių, mes niekada nedarome piramidės.

waitPromise (2000)

.tada (() => {

console.log ('Pirmasis skambutis!');

grįžti laukti Pažadas (3000);

  })

.tada (() => {

console.log ('Antrasis skambinimas!');

grįžti palaukti Pažadas (4000);

  })

.tada (() => {

console.log ('Antrasis skambinimas!');

grįžti palaukti Pažadas (4000);

  });

Dar geriau, jei mums reikia koordinuoti asinchronines užduotis, palaikančias „Promises“, galėtume tai naudoti visi, kuris yra statinis metodas Pažadas objektas, kuris prisiima kelis pažadus ir sujungia juos į vieną. Tai atrodytų taip:

Promise.all ([

waitPromise (2000),

waitPromise (3000),

palaukti Pažadas (4000)

]). tada (() => console.log ('Viskas padaryta!'));

Kitą savaitę toliau gilinsimės į tai, kaip veikia pažadai ir kaip idiomatiškai jais pasinaudoti. Jei tik mokotės „JavaScript“ arba norite išbandyti savo žinias, pabandykite palaukPaskambinimas arba pabandykite atlikti lygiavertį Pažadėk.visi su atšaukimais.

Kaip visada, susisiekite su manimi „Twitter“ su bet kokiais komentarais ar klausimais.

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