我有以下代码:
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")
之后执行。有人可以向我解释吗?
答案 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));
})()