функция async - ждать, не дожидаясь обещания

Я пытаюсь изучить async-await. В этом коде -

const myFun = () => {
    let state = false;

    setTimeout(() => {state = true}, 2000);

    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if(state) {
                resolve('State is true');
            } else {
                reject('State is false');
            }
        }, 3000);
    });
}

const getResult = async () => {
    return await myFun();
}

console.log(getResult());

почему я получаю вывод как -

Promise { <pending> }

Вместо какой-то ценности? Разве функция getResult() не должна ждать, пока myFun() функция не разрешит значение обещания?


person hg_git    schedule 25.08.2017    source источник
comment
асинхронные функции всегда возвращают обещание. getResult ожидает разрешения myFunc. затем он возвращает значение в обещании.   -  person tumelo    schedule 15.06.2021


Ответы (4)


Если вы используете async / await, все ваши вызовы должны использовать Promises или async / await. Вы не можете просто волшебным образом получить асинхронный результат от вызова синхронизации.

Ваш последний звонок должен быть:

getResult().then(response => console.log(response));

Или что-то вроде:

(async () => console.log(await getResult()))()
person Ben Fortune    schedule 25.08.2017
comment
почему последний async (тот, что с IIFE) становится синхронным, но не мой getResult() метод? - person hg_git; 25.08.2017
comment
@hg_git Потому что он заключен в асинхронный IIFE с вызовом await. Это не становится синхронным, это просто синтаксический сахар. - person Ben Fortune; 25.08.2017
comment
в моем getResult() также есть async ключевое слово и await вызов .. - person hg_git; 25.08.2017
comment
какая разница ч / б два? - person hg_git; 25.08.2017
comment
@hg_git Но вы получаете результат getResult(), это все еще обещание. - person Ben Fortune; 25.08.2017
comment
@hg_git: async функции возвращают обещания. await волшебным образом разворачивает обещание перед выполнением следующего кода. Код выглядит синхронным, но не выполняется синхронно. - person Felix Kling; 25.08.2017

Что вам нужно понять, так это то, что async / await не заставляет ваш код работать синхронно, но давайте вы напишете его так, как будто это есть:

Вкратце: функция с async перед ней буквально выполняется асинхронно, отсюда и ключевое слово «async». И ключевое слово "await" заставит эту строку, которая использует его внутри этой асинхронной функции, ждать обещания во время его выполнения. Таким образом, хотя строка ожидает, вся функция по-прежнему выполняется асинхронно, если только вызывающий объект этой функции не «ожидает» ...

Более подробно объясняется: когда вы помещаете async перед функцией, на самом деле она заставляет ее возвращать обещание с тем, что эта функция возвращает внутри него. Функция выполняется асинхронно, и при выполнении оператора return обещание разрешает возвращаемое значение.

Это означает, что в вашем коде:

const getResult = async () => {
    return await myFun();
}

Функция getResult () вернет обещание, которое разрешится после завершения выполнения. Таким образом, строки внутри функции getResult () выполняются асинхронно, если только вы не укажете функции, вызывающей getResult (), «ждать» и для нее. Внутри функции getResult () вы можете сказать, что она должна ждать результата, что заставляет выполнение getResult () ждать, пока она не разрешит обещание, но вызывающий getResult () не будет ждать, если вы также не скажете вызывающей стороне `` ждать '.

Таким образом, решение будет называть либо:

getResult().then(result=>{console.log(result)})

Или при использовании в другой функции вы можете просто снова использовать "ожидание"

async callingFunction(){
    console.log(await(getResult());
}
person Pim_nr_47    schedule 30.05.2019
comment
Хорошее объяснение! Здесь вы можете увидеть рабочий пример: codepen.io/juanmamenendez15/pen/YzPqeKj?editors= 0012 - person Juanma Menendez; 11.12.2019

Нет смысла использовать async и await, когда это действительно так:

Promise.resolve(3).then(console.log); console.log(4);
4
3

Другими словами, поскольку then () разветвляется и работает медленнее, чем последующие операторы (даже для разрешенного обещания), нам нужно поместить последующие операторы внутри then, например:

Promise.resolve(3).then(_ => { console.log(_); console.log(4); });
3
4

И если это правда, то зачем ждать. Так что мне еще предстоит понять, почему существуют async и await.

person ekerner    schedule 12.12.2018
comment
в типичном случае вы не видите обещания, используемые для передачи литералов, они используются для передачи из источника с привязкой к контексту (устройства ввода-вывода, такого как сеть). В таких случаях вы можете хотите написать код с видом / стилем последовательного выполнения, используя _1 _ / _ 2_. это устраняет необходимость и сложность написания явных продолжений с использованием then(), что приводит к более удобочитаемому коду, меньшим усилиям и аналогичному поведению. значение обещаний - это отсрочка, поэтому процессор может быть уступлен кодом, когда / когда он знает, что ему придется подождать. тем не менее, вы можете получить лучший ответ, разместив свой ответ в виде вопроса. - person Shaun Wilson; 06.01.2020
comment
@ ekerner, Спасибо, ваш комментарий помог решить мою проблему. Моя проблема заключалась в том, что когда я запускал сервер NodeJS, при первом вызове функции async await код сервера выполнялся, не дожидаясь выполнения обещания. Я использовал then(value) для заполнения массива, но к тому времени, когда он был заполнен, остальная часть кода уже выполнялась. Странно это происходило, когда я повторял действие. Это всегда происходило один раз при перезапуске сервера NodeJS. Итак, теперь я вставил весь серверный код внутрь then(value) =>, и логика работает нормально. - person AwsAnurag; 12.12.2020

Это моя обычная работа с await и async с использованием Promise с resolve и reject механизм

    // step 1 create a promise inside a function
    function longwork()
    {
        p =  new Promise(function (resolve, reject) {
            result = 1111111111111 // long work here ; 

            if(result == "good"){
                resolve(result);
            }
            else
            {
                reject("error ...etc")
            } 
        })

        return p
    }

    // step 2 call that function inside an async function (I call it main)and use await before it
    async function main()
    {
         final_result = await longwork();
         //..

    }  

    //step 3 call the async function that calls the long work function
    main().catch((error)=>{console.log(error);})

Надеюсь, что это сэкономит кому-то драгоценные часы

person Nassim    schedule 21.05.2020