Cum funcționează async/await și Promise în TypeScript


Am o mică funcție pentru a învăța cum funcționează async, await și promise aici.

function delay(ms: number) {
    return new Promise<void>(function(resolve) {
       setTimeout(resolve, ms);
    });
}

async function asyncAwait() {
    console.log("A");

    await delay(1000);
    console.log("B");

    await delay(1000);
    console.log("C");
}

asyncAwait();
console.log("D");

Din înțelegerea mea, fluxul de lucru ar fi așa,

apelează asyncAwait(); mai întâi, apoi tipărește A, apoi așteaptă 1s și tipărește B apoi așteaptă încă 1s și tipărește C și în final tipărește D.

dar ieșirea mea este de genul,

A
D
B
C

Nu știu de ce console.log("D") se afișează al doilea.

Poate cineva să explice codul de mai sus?

mulțumesc anticipat

Răspuns #1

Așa funcționează apelurile asincrone.

Cum crezi că este execuția codului:

function delay(ms: number) {
    return new Promise<void>(function(resolve) {
       setTimeout(resolve, ms);
    });
}

async function asyncAwait() {
    console.log("A");

    await delay(1000);
    console.log("B");

    await delay(1000);
    console.log("C");
}

asyncAwait();   // <-- 1st call
console.log("D");

Apoi în interiorul acelei funcții:

async function asyncAwait() {
    console.log("A");  // <--- 1st print, as it is synchronous

    await delay(1000); // <--- await
    console.log("B");  // <--- 2nd print

    await delay(1000); // <-- await
    console.log("C");  // <-- 3rd print
}

Și apoi în sfârșit

function delay(ms: number) {
    return new Promise<void>(function(resolve) {
       setTimeout(resolve, ms);
    });
}

async function asyncAwait() {
    console.log("A");

    await delay(1000);
    console.log("B");

    await delay(1000);
    console.log("C");
}

asyncAwait();
console.log("D"); // <-- last print

DAR, funcția async este asincronă. Așadar, toate apelurile async merg în coadă și sunt procesate mai târziu.

Prin urmare, mai întâi sunt executate apelurile sincrone:

console.log("A");
console.log("D");

Și apoi apelurile asincrone.

await funcționează doar în interiorul unei funcții async.

Deci funcția:

async function asyncFunc() {
  console.log("A");

  await delay(1000);
  console.log("B");
}

este aproximativ echivalent cu acesta:

asyncFunc() {
  console.log('A');
  delay().then(()=> {
     console.log('B');
  });
}

Deci, dacă vrei ca console.log("D") să fie executat după funcția asincronă, ar trebui să aștepți funcția asincronă. Dar pentru a folosi await, trebuie să fii într-o funcție asincronă:

async function asyncFunc2() {
  await asyncAwait();
  console.log("D");
}

asyncFunc2();

Răspunsul #2

Trebuie să await apelul asyncAwait():

function delay(ms: number) {
    return new Promise<void>(function(resolve) {
       setTimeout(resolve, ms);
    });
}

async function asyncAwait() {
    console.log("A");

    await delay(1000);
    console.log("B");

    await delay(1000);
    console.log("C");
}

async function main() {
    await asyncAwait();
    console.log("D");
}

main();