Doprovodný zdrojový kód: async_await_html.zip

Intro

Většina procedurálních jazyků primárně používá blokující funkce

Například v pythonu:

jmeno = input('Kdo jsi?\n') # zde se čeká dokud uživatel nenapíše jméno
# teď můžu pracovat s hodnotou proměnné jméno, mám ji načtenou
print(f"Ahoj {jmeno}")

K zajištění asynchronicity (například program něco počítá, ale uživatel dál něco nastavuje v okně programu) se používají o něco (zápisem) komplikovanější postupy, které vnitřně používají vlákna (thready).

V javascriptu je to opačně. Přirozené použití vede na asynchronitu. Primárně se používají události (events); na něco jsou skvělé, na jiné věci méně.

Uvnitř funguje jednovláknový „event loop“ - ucelené kusy výpočtu se naplánují a postupně vykonají.

Eventy

Callbacky

Často je výsledkem callback hell


Řešení (2012 ale dlouho trvalo než probublalo do prohlížečů)

Promises

        let myPromise = new Promise(function(myResolve, myReject) {
            // "Producing Code" (May take some time)
 
            myResolve(); // when successful
            myReject();  // when error
        });
 
        // "Consuming Code" (Must wait for a fulfilled Promise)
        myPromise.then(
          function(value) { /* code if successful */ },
          function(error) { /* code if some error */ }
        );

Zdánlivě jen další příklad callbacku, ale `.then()` lze řetězit

new Promise(function(resolve, reject) {
  setTimeout(() => resolve(1), 1000); // (*)
}).then(function(result) { // (**)
  alert(result); // 1
  return result * 2;
}).then(function(result) { // (***)
  alert(result); // 2
  return result * 2;
}).then(function(result) {
  alert(result); // 4
  return result * 2;
});

a existující callback funkce lze převést na promisy

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
  const nactiStranku = new Promise(function(myResolve, myReject) {
    const xhttp = new XMLHttpRequest();
    xhttp.onload = function() {
      myResolve(xhttp)
    }
    xhttp.onerror = function(){
      myReject()
    }
    // Send a request
    xhttp.open("GET", "ajax_info.txt");
    xhttp.send();
  });

Async/Await

Proč vůbec stále psát then() ? Pojďmě udělat speciální kategorii funkcí, které označíme async

Příklad výsledného kódu:

 const pokemoni = await nactiSeznamPokemonu()
 const grafika = await nactiObrazkyPokemonu(pokemoni)
 await pockejNaMezeru()
 zacniHru()
 /* ... */

Jediný implementační problém: await může být použit pouze uvnitř asynchronních funkcí.

Nejsnazší řešení (ne vždy ideální ;)):

        setTimeout(async function(){
            // Tady už jsme v async/await prostředí (tato funkce je async)
            await sleep(1000)
            alert('Hello')
        })