Когда разрешается обещание асинхронной функции? - PullRequest
0 голосов
/ 06 июля 2018

У меня есть код ниже:

let func = () => {
    return new Promise((resolve) => {
        setTimeout(() => {
            console.log("two");
            resolve();
        }, 3000);
    })
};

let func2 = async () => {
    console.log("one");
    await func();
    console.log("three");
}

(async () => {
    await func2();
    console.log("main"); // This should never be executed
})()

Заметил func2 никогда не возвращает значение, обещание, возвращаемое func2 никогда не должно быть выполнено по моему мнению. Следовательно, console.log("main") никогда не должен выполняться. Однако он выполняется после console.log("three"). Может кто-нибудь объяснить это мне?

Ответы [ 4 ]

0 голосов
/ 06 июля 2018

Замечено, что func2 никогда не возвращает значение, обещание, возвращаемое func2, по моему мнению, никогда не должно выполняться.

Это не так, как работают асинхронные функции. Ваш func2 возвращается, когда все будет выполнено. Возвращаемым значением функции без оператора return является конкретное значение undefined. Таким образом, undefined становится разрешенным значением обещания. Помните, в Javascript undefined - это конкретное значение. Это как если бы вы сделали return undefined в конце вашего функционального блока. Таким образом, поскольку undefined является возвращаемым значением, оно становится разрешенным значением обещания async.


Чтобы полностью охватить все базы, функции async всегда возвращают обещание, и это обещание получает разрешенное / отклоненное значение одним из следующих способов:

1. Когда вы явно return получаете значение из функции. Это становится разрешенным значением обещания, которое возвращает функция async.

async function test() {
    return "hello";
}

test().then(val => {
    console.log(val);      // "hello"
});

2. Когда вы генерируете исключение. Исключение становится причиной отклонения обещания, которое возвращает функция async.

async function test() {
    throw new Error("ouch");
}

test().catch(err => {
    console.log(err);      // Shows error object with message "ouch"
});

3. Когда вы возвращаете другое обещание. Это обещание приковано к тому, которое возвращает асинхронная функция, и обещание, которое возвращает асинхронная функция, будет следовать за тем, которое вы вернули (разрешите, если оно разрешится с тем же значением или отклоните по той же причине ).

async function test() {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve("hi");
        }, 1000);
    });
}

test().then(val => {
    console.log(val);      // "hi"
});

4. Когда вы ничего не возвращаете. Это то же самое, что и в обычных функциях, и это эквивалентно return undefined в конце функционального блока, поэтому разрешенное значение принимает значение undefined.

Итак, это:

async function test() {
    console.log("hi");
}

test().then(val => {
    console.log(val);      // undefined
});

Работает точно так же, как это:

async function test() {
    console.log("hi");
    return undefined;
}

test().then(val => {
    console.log(val);      // undefined
});
0 голосов
/ 06 июля 2018

Функция async не требует возвращаемого значения для разрешения. Он считается решенным, когда завершается без ошибок.

Если вы throw new Error() внутри func2, console.log("main") никогда не будет выполнено.

0 голосов
/ 06 июля 2018

Когда вы не возвращаетесь из функции, она неявно возвращает значение по умолчанию - обычно неопределенное. Таким образом, обещание, возвращаемое func2, все равно разрешится, когда функция вернется.

От MDN :

Функция без оператора возврата будет возвращать значение по умолчанию. В случай конструктора, вызванного с новым ключевым словом, по умолчанию значение это значение этого параметра. Для всех других функций возвращаемое значение по умолчанию не определено.

Вы можете увидеть это в своем коде, если измените его на следующее:

(async () => {
    func2()
    .then(d => console.log(d));
})()
0 голосов
/ 06 июля 2018

Функция, которая явно не возвращает что-то, на самом деле возвращает undefined:

function test() { }
console.log(test());

То же самое с асинхронными функциями, они также разрешаются в undefined, когда не было возвращено никакого другого значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...