简体   繁体   English

Javascript等待/异步执行顺序

[英]Javascript await/async order of execution

So I'm trying to wrap my head about promises/await/async.所以我试图把我的头放在 promises/await/async 上。 I can't understand why when go() is executed the alert with "finished" go right after the console.log(coffee).我不明白为什么当执行 go() 时,在 console.log(coffee) 之后会出现带有“finished”的警报。 Why does it only wait for getCoffee() and the other axios calls are ran after the "finished" alert when all functions are using await/promises?当所有函数都使用 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>

The issue here is that console.log isn't always as synchronous as one might think.这里的问题是console.log并不总是像人们想象的那样同步。 The specification only requires that console.log display a message in the developer console, but doesn't make any requirements about how or when the message will display.该规范仅要求console.log在开发者控制台中显示一条消息,但没有对消息的显示方式或时间提出任何要求。 Depending on your browser, results may differ, however usually it's implemented something like the following:根据您的浏览器,结果可能会有所不同,但通常它的实现方式如下:

  • When you make a call to console.log the request gets pushed onto a stack (so consecutive calls to console.log always execute in order)当您调用console.log ,请求会被推送到堆栈上(因此对console.log连续调用始终按顺序执行)
  • On the next animation frame, the browser will attempt to process as much of the stack as possible (minimum of one element on the stack must be processed, so the browser may lock up if you attempt to log 8 megabytes of data)在下一个动画帧中,浏览器将尝试处理尽可能多的堆栈(必须至少处理堆栈中的一个元素,因此如果您尝试记录 8 兆字节的数据,浏览器可能会锁定)
  • "Processing" the stack involves things like converting DOM element references to links that take you elsewhere in the dev console, converting JSON objects to navigable and collapsible UI elements, or replacing objects with the text "[Object object]" “处理”堆栈涉及诸如将 DOM 元素引用转换为可将您带到开发控制台中其他位置的链接、将 JSON 对象转换为可导航和可折叠的 UI 元素或将对象替换为文本“[Object object]”之类的事情
  • Once an element on the stack is processed, it must be rendered in the console.一旦堆栈上的元素被处理,它必须在控制台中呈现。 This requires adjusting the height of the console, determining if you need a scroll bar, determining where text will wrap, etc. This process (taking what you want in the console and actually displaying it on the screen) is called "painting"这需要调整控制台的高度,确定是否需要滚动条,确定文本的换行位置等。这个过程(在控制台中取出你想要的并实际显示在屏幕上)称为“绘画”

Because console.log is actually a complex operation like this, it may not finish executing before the alert statement runs (in some browsers).因为console.log实际上是这样一个复杂的操作,它可能在alert语句运行之前执行不完(在某些浏览器中)。 By replacing every call to alert with console.log or every call to console.log with alert you should see that things are actually executing in the expected order.通过每次调用替换到alertconsole.log或每次调用console.logalert ,你应该看到的东西实际上是在期待的顺序执行。

The async/await is working as intended. async/await 正在按预期工作。 It is just that the the console takes some time to update or the browser is repainting, therefore the alert is triggered before it can repaint.只是控制台需要一些时间来更新或浏览器正在重新绘制,因此在重新绘制之前触发了alert You can verify it by using all alert instead of console.log .您可以使用 all alert而不是console.log来验证它。 All the alert are executed in the correct order.As shown in the example below.所有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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM