Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Вопрос про async/await (https://javascript.ru/forum/misc/81255-vopros-pro-async-await.html)

vlad_kl 29.10.2020 23:38

Вопрос про async/await
 
Доброго времени суток, уважаемые знатоки.
Столкнулся с такой проблемой
Ниже простой код.
Первая функция num10 явно возвращает промис, т.к. там new Promise
Вторая функция num11 тоже возвращает промис, т.к. обёрнута в async.
https://learn.javascript.ru/async-await

Вопрос: :help: :help: :help:
почему в третьей функции
* await num10() - работает КАК ПОЛОЖЕНО (браузер ждёт выполнения функции num10, консолит то, что она возвращает и идёт дальше)
* await num11() - НЕ РАБОТАЕТ (браузер не дожидается выполнения этой функции, её результат консолится в самом конце).

Почему так? Ведь обе функции num10 и num11 вроде как промисы.
Почему одно работает, другое нет.

Никак в толк взять не могу.
Буду очень благодарен за ваши ответы
Если вдруг где-то туплю и вопрос совсем глупый - не судите строго. Не ошибается тот, кто ничего не делает :victory:


function num10 () {
    return new Promise((resolve, reject)=> {
        setTimeout(()=>{
            resolve(10*10)
        }, 3000); 
    }).then(
        value => console.log(value),
    );
}


async function num11 () {
    setTimeout(()=> {
        let num = 11 * 11;
        return console.log(num);
    }, 3000);
}


async function waitCount() {
    console.log('1');
    console.log('2');
    await num10();
    console.log('3');
    await num11();
    console.log('4');
}

waitCount();

voraa 30.10.2020 08:03

Потому, что num11 возвращает сразу разрешенный Promise
Реально она работает так

function num11 () {
    setTimeout(()=> {
        let num = 11 * 11;
        return console.log(num);
    }, 3000);

    return Promise.resolve(undefined);
}

vlad_kl 30.10.2020 11:03

Цитата:

Сообщение от voraa (Сообщение 530201)
Потому, что num11 возвращает сразу разрешенный Promise
Реально она работает так

function num11 () {
    setTimeout(()=> {
        let num = 11 * 11;
        return console.log(num);
    }, 3000);

    return Promise.resolve(undefined);
}

Вы уверены, что причина именно в этом??
Ну возвращает промис в num11 undefined, и что? Вопрос не в том, что он возвращает, а в том, КОГДА он срабатывает.

А разве в функции num10 не указано, что промис будет разрешённый? Там же тоже стоит резолв.

SuperZen 30.10.2020 11:59

async/await для Promise, setTimeout != promise )

num10 возвращает promise,
num11 не возвращает промис

https://tc39.es/ecma262/#await
https://jakearchibald.com/2015/tasks...and-schedules/
https://www.digitalocean.com/communi...-in-javascript

vlad_kl 30.10.2020 12:08

Цитата:

Сообщение от SuperZen (Сообщение 530210)
async/await для Promise, setTimeout != promise )

num10 возвращает promise,
num11 не возвращает промис

https://tc39.es/ecma262/#await
https://jakearchibald.com/2015/tasks...and-schedules/
https://www.digitalocean.com/communi...-in-javascript


А если верить учебнику, то async ВСЕГДА возвращает промис.
И не важно, что внутри функции написан setTimeout, это просто для имитации задержки.
Даже если внутри async function будет написано просто return 1 и всё - всё равно это будет ПРОМИС с результатом 1.
Пожалуйста, вот линк

https://learn.javascript.ru/async-aw...onnye-funktsii

SuperZen 30.10.2020 12:21

кому-то стоить сделать calmdown )) на заборе тоже х написано, а там дрова ))

ну так
function a() {}
console.log(a()) // undefined


num11 и возвращает undefined ) а то что там происходит в setTimeout так это про event loop надо читать...

voraa 30.10.2020 13:16

Цитата:

Сообщение от vlad_kl
Ну возвращает промис в num11 undefined, и что? Вопрос не в том, что он возвращает, а в том, КОГДА он срабатывает.

А разве в функции num10 не указано, что промис будет разрешённый? Там же тоже стоит резолв.

А вы разницу не видите?
num10 запускает таймер и возвращает промис, который разрешится после срабатывания таймера.
А num11 запускает таймер и возвращает уже разрешенный промис. А таймер сам по себе когда-нибудь сработает

voraa 30.10.2020 13:18

Цитата:

Сообщение от SuperZen
num11 и возвращает undefined

Нет. В исходном варианте (первый пост) num11 возвращает промис.

SuperZen 30.10.2020 14:58

voraa, Ты прав... Куда-то не туда смотрел )

async function a() { }
  console.log(a())
  /**
  Promise
    __proto__: Promise
      [[PromiseState]]: "fulfilled"
      [[PromiseResult]]: undefined
  */

vlad_kl 31.10.2020 14:34

Цитата:

Сообщение от voraa (Сообщение 530219)
А вы разницу не видите?
num10 запускает таймер и возвращает промис, который разрешится после срабатывания таймера.
А num11 запускает таймер и возвращает уже разрешенный промис. А таймер сам по себе когда-нибудь сработает

Т.е., если я правильно понял, await ожидает завершения выполнения промиса (а не всего кода внутри промиса). Как только промис завершился удачно (даже если там ещё остался какой-то асинхронный код), интерпретатор идёт далее.

В 1м случае в num10 в конструкции new Promise - промис завершится ТОЛЬКО ТОГДА, когда завершится setTimeout, поэтому код ждёт весь setTimeout.
Во 2м случае в num11 async сразу возвращает зарезолвленный промис несмотря на весь код, который внутри async функции. Поэтому await дождался завершения выполнения промиса - и пошёл дальше. А сам setTimeout внутри async функции попал в call stack и выполнился позже. Намного позже, чем выполнение промиса.

Верно? Это очень тонкое отличие... :write: :write:
Спасибо большое всем за помощь :victory: :victory:


Часовой пояс GMT +3, время: 18:32.