异步功能何时会解决?

时间:2018-07-06 00:57:36

标签: javascript node.js async-await

我有以下代码:

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 :(得分:2)

  

带修饰符的func2永远不会返回值,在我看来,func2返回的诺言永远都不能实现。

这不是异步功能的工作方式。您的func2执行完毕后会返回。没有return语句的函数的返回值是特定值undefined。因此,undefined成为承诺的已解决价值。请记住,在Javascript中,undefined是一个特定值。就像您在功能块末尾进行了return undefined一样。因此,由于undefined是返回值,因此它成为async Promise的已解析值。


要完全覆盖所有基础,async函数始终返回一个promise,并且promise将获得已解决/被拒绝的值,这些方式之一:

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函数返回的诺言,并且async函数返回的诺言将遵循您返回的诺言(当它以相同的值解析或以相同的值拒绝时,即为解析原因)。

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

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

4。当您不返回任何内容时。与常规函数相同,它等效于功能块末尾的return undefined,因此解析后的值将为undefined的值。 / p>

所以,这个:

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
});

答案 1 :(得分:1)

一个不会返回任何内容的函数,实际上会返回undefined

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

与异步函数相同,当没有其他值返回时,它们也解析为undefined

答案 2 :(得分:1)

async函数不需要返回值即可进行解析。完成执行而没有错误时,它将被视为已解决。

如果您在throw new Error()func2,将永远不会执行console.log("main")

答案 3 :(得分:1)

当您不从函数返回时,它隐式返回一个默认值-通常是未定义的。因此,func2返回的promise在函数返回时仍将解决。

来自MDN

  

没有return语句的函数将返回默认值。在   用new关键字调用构造函数的情况,默认   value是其此参数的值。对于所有其他功能,   默认返回值是不确定的。

如果将其更改为此,则可以在代码中看到它:

(async () => {
    func2()
    .then(d => console.log(d));
})()