MDN documentation声明
当调用异步函数时,它返回一个Promise。当异步时 函数返回一个值,Promise将被解析 返回值。当异步函数抛出异常或某些异常时 价值,承诺将以抛出的价值被拒绝。
因此,考虑到await
期望已经解决的承诺,我做错了什么?
foo();
async function foo(){
await bar();
zoo();
}
async function bar(){
setTimeout(() => {
console.log("bar");
return;
}, 1000);
}
function zoo(){
console.log("zoo");
}
根据我(错误地)理解的内容,它应首先记录bar
然后记录zoo
,但它会以相反的方式记录。
编辑:现在,感谢@Matt Morgan的澄清,我理解错误,因为bar()
函数返回undefined
。尽管如此,我认为通过单独调用async
函数本身会使函数立即返回一个未解析的promise,并且当async
函数返回时这样的promise将得到解决任何值(甚至未定义)。但我现在意识到,真的需要通过return Promise
语句声明它来回复自己的承诺。我认为我所读到的async
的MDN文章在这个主题上有点令人困惑(仅仅是我的意见)。
因此,我可以简单地将bar()
函数修改为:
function bar(){
return new Promise(function(resolve){
setTimeout(() => {
console.log("bar");
resolve();
}, 1000);
});
}
答案 0 :(得分:3)
bar()
正在设置超时并返回undefined,这与立即运行超时结束时运行的日志语句不同。
因此,zoo()
运行,然后当超时结束(1000毫秒后)时,您会看到" bar"在控制台中。
这是一个修改过的示例没有超时:
foo();
async function foo(){
await bar();
zoo();
}
async function bar(){
console.log("bar");
}
function zoo(){
console.log("zoo");
}

如果没有setTimeout
,您将获得预期的执行顺序。
第二个例子,你有一个delay()
函数将setTimeout
包装在一个承诺中:
foo();
async function foo(){
await bar();
zoo();
}
async function bar(){
await delay();
console.log("bar");
}
function delay(t, v) {
return new Promise(function(resolve) {
setTimeout(resolve.bind(null, v), t)
});
}
function zoo(){
console.log("zoo");
}

最终代码段 等待承诺的解决,因此您会看到bar
,然后foo
。
以上delay
取自https://stackoverflow.com/a/39538518/3084820
这是最后一个例子,bar()
返回" bar"。这意味着它会被async
声明包含在承诺中,并由await
内部foo()
解决。再次,您会看到您希望看到的内容。
foo();
async function foo(){
console.log(await bar());
zoo();
}
async function bar(){
return 'bar';
}
function zoo(){
console.log("zoo");
}

了解原始示例不会返回值bar
非常重要。它返回undefined
,如果您更改原始代码以注销返回的bar()
值,您将在控制台中看到三件事:
bar()
,解析为undefined
。zoo
函数的值zoo()
。bar
中记录的setTimeout
已被推入队列。试一试,看看你得到了什么。