JS Async / Await vs Promise vs Callbacks

Sep 14 2020

Próbuję zrozumieć różnicę między tymi 3. Wywołania zwrotne i obietnice są jasne, ale nie używam async / await. Wiem, że to cukier składniowy obietnic, ale to, czego próbowałem, nie zadziałało. Dzielę się fragmentem kodu, który próbowałem to wszystko zrozumieć ...

Próbowałem z tablicą

var array = [1,2,3];

i 2 funkcje

  • get() wykonuje w 1 sekundę i konsolę array
  • post(item) wykonuje w 2 sekundy i wypycha nowy element w array

Teraz chcę uzyskać, aby postmetoda została wykonana najpierw i getpo niej, aby wynik na konsoli [1,2,3,4]nie był[1,2,3]

ODDZWONIĆ

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item, callback) {
    setTimeout(() => {
        array.push(item);
        callback();
    }, 2000);
}

function init() {
    post(4, get);
    // returns [1,2,3,4] ✅
}

Działa dobrze, ale w przypadku zbyt wielu wywołań zwrotnych kod będzie bardziej niechlujny ... Więc

OBIETNICA

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}

function init() {
    post(4).then(get);
    // returns [1,2,3,4] ✅
}

Ok z dużo czystszym kodem. Ale wciąż wiele thenpołączeń ... Teraz,

Async / Await

function get() {
    setTimeout(() => console.log(array), 1000);
}

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    await post(4);
    get();
    // returns [1,2,3] ❌

    await post(4);
    await get();
    // returns [1,2,3] ❌

    post(4);
    await get();
    // returns [1,2,3] ❌
}

O wiele bardziej przejrzysta wersja, ale tak czy inaczej, działało ... Próbowałem też tego (przekonwertuj obie funkcje ( post& get) na asynchroniczne i zadzwoń z then)

async function get() {
    setTimeout(() => console.log(array), 1000);
}

async function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

async function init() {
    post(4).then(get);
    // returns [1,2,3] ❌
}

Ale nadal bezużyteczne. Więc jestem całkowicie zdezorientowany co do tej funkcji (tj. Async / await). Opisz, proszę, właśnie ten przykład. A także proszę, opowiedz mi o Promise.resolve& Promise.allw tym samym kontekście! Dzięki

Odpowiedzi

3 Quentin Sep 13 2020 at 22:35

asynci awaitsą narzędziami do zarządzania obietnicami

await post(4);

Tutaj czekasz, aż zwrócona obietnica postzostanie rozwiązana.

function post(item) {
    setTimeout(() => {
        array.push(item)
    }, 2000);
}

Jednak post nie zwraca obietnicy , więc nie robi nic użytecznego.

Miałeś już działającą implementację postz obietnicą. Więc użyj tego:

function post(item) {
    return new Promise((resolve, reject) => setTimeout(() => {
        array.push(item)
        resolve();
    }, 2000));
}
2 trincot Sep 13 2020 at 22:38

Twoje próby asynci awaitnie używaj niczego, co rozwiązuje obietnicę po opóźnieniu . W obecnej postaci wszystkie asynczdefiniowane przez Ciebie funkcje zwracają obietnicę, która natychmiast się rozwiązuje.

Będziesz chciał użyć funkcji narzędzia, z której często możesz korzystać. Zwraca obietnicę, która jest rozpatrywana po określonej liczbie milisekund, używając setTimeout:

// utility function
let delay = ms => new Promise(resolve => setTimeout(resolve, ms));

let array = [1, 2, 3];

async function get() {
    await delay(1000);
    console.log(array);
}

async function post(item) {
    await delay(1000);
    array.push(item)
}

async function init() {
    await post(4);
    await get();
}

init();
console.log("wait for it...");

1 tawfiknasser Sep 13 2020 at 22:31

Podobnie jak w przypadku PROMISE .

Owiń post setTimeout w obietnicę i zwróć go.
call solution w treści settimeout.

function post(item) {
 return new Promise((resolve)=>{
   setTimeout(() => {
     array.push(item)
     resolve()
   }, 2000);
 })
}

wtedy możesz go używać w ten sposób:

async function init() {
    await post(4);
    get();
    }