javascript - Javascript等待/异步执行顺序
问题描述
所以我试图把我的头放在promises/await/async上。我不明白为什么当执行 go() 时,在 console.log(coffee) 之后立即出现带有“finished”的警报。当所有函数都使用等待/承诺时,为什么它只等待 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>
解决方案
这里的问题console.log
是并不总是像人们想象的那样同步。该规范只要求console.log
在开发者控制台中显示一条消息,但对消息的显示方式或时间没有任何要求。根据您的浏览器,结果可能会有所不同,但通常实现如下:
- 当您
console.log
对请求进行调用时,会被推送到堆栈上(因此连续调用console.log
总是按顺序执行) - 在下一个动画帧上,浏览器将尝试处理尽可能多的堆栈(必须处理堆栈中的至少一个元素,因此如果您尝试记录 8 兆字节的数据,浏览器可能会锁定)
- “处理”堆栈包括将 DOM 元素引用转换为将您带到开发控制台中其他位置的链接、将 JSON 对象转换为可导航和可折叠的 UI 元素或用文本“[Object object]”替换对象
- 一旦堆栈上的元素被处理,它必须在控制台中呈现。这需要调整控制台的高度,确定是否需要滚动条,确定文本将在哪里换行等。这个过程(在控制台中获取您想要的内容并实际显示在屏幕上)称为“绘画”
因为实际上是这样一个复杂的操作,它可能在语句运行console.log
之前执行不完(在某些浏览器中)。alert
通过将每次调用替换为alert
或console.log
每次调用替换为console.log
,alert
您应该会看到事情实际上是按照预期的顺序执行的。
推荐阅读
- python - 我想让python在这个计算器中识别“num1”和“num2”是否是数字,以便python可以通知你没有输入有效的东西
- git - 解决报告的合并冲突后,是否需要重复运行相同的合并命令?
- javascript - 使用 lambda 在 socket.io 中发送 2 个参数的正确方法是什么?(在客户端和服务器中打印时我得到未定义)
- javascript - React - 子到父回调不起作用
- postgresql - 将json数组元素插入表的函数
- apache-spark - Spark Select 对不同对象的 JSON 数组进行选择
- arrays - 如何修复 yii2 BaseActiveRecord 无法显示、私有的 mongodb 数组?
- r - 对于 XY 坐标对,使用数据表,计算行数,将完整集写入 DT1,DT2 部分集
- raku - `MAIN()` 参数中的字符串匹配
- php - PHP 无法加载大于 1MB 的 PDF