因此,我正在努力答应Promise / await / async。我不明白为什么在执行go()时,会在console.log(coffee)之后立即显示“已完成”的警报。当所有函数都使用await / promises时,为什么只等待getCoffee()和其他“ axios”调用在“完成”警报之后运行?
function getCoffee() {
return new Promise(resolve => {
setTimeout(() => resolve("☕"), 2000); // it takes 2 seconds to make coffee
});
}
async function go() {
try {
alert("ok");
const coffee = await getCoffee();
console.log(coffee); // ☕
const wes = await axios("https://randomuser.me/api/?results=200");
console.log("wes"); // using string instead of value for brevity
const wordPromise = axios("https://randomuser.me/api/?results=200");
console.log("wordPromise"); // using string instead of value for brevity
alert("finish");
} catch (e) {
console.error(e); //
}
}
go();
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
答案 0 :(得分:1)
这里的问题是console.log
并不总是像人们想象的那样同步。该规范仅要求console.log
在开发人员控制台中显示消息,而不对消息的显示方式或时间提出任何要求。视您的浏览器而定,结果可能会有所不同,但是通常会实现以下内容:
console.log
时,请求会被推送到堆栈上(因此,对console.log
的连续调用总是按顺序执行)由于console.log
实际上是一个复杂的操作,因此它可能在alert
语句运行之前(在某些浏览器中)无法完成执行。通过用alert
替换对console.log
的每次调用或用console.log
替换对alert
的每次调用,您应该看到事情实际上正在按预期的顺序执行。
答案 1 :(得分:1)
异步/等待正在按预期方式工作。只是控制台需要花费一些时间来更新或浏览器正在重新绘制,因此alert
在重新绘制之前被触发。您可以使用所有alert
而不是console.log
进行验证。所有alert
均以正确的顺序执行。如下例所示。
function getCoffee() {
return new Promise(resolve => {
setTimeout(() => {resolve("coffee")}, 2000); // it takes 2 seconds to make coffee
});
}
async function go() {
try {
alert("ok");
const coffee = await getCoffee();
alert(coffee); // ☕
const wes = await getCoffee();
alert(wes);
const wordPromise = getCoffee();
alert(wordPromise);
alert("finish");
} catch (e) {
console.error(e); //
}
}
go();